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__anon5b5425d00111::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__anon5b5425d00111::DSAStackTy::ReductionData130     void set(BinaryOperatorKind BO, SourceRange RR) {
131       ReductionRange = RR;
132       ReductionOp = BO;
133     }
set__anon5b5425d00111::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__anon5b5425d00111::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__anon5b5425d00111::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   FunctionEmissionStatus FES = getEmissionStatus(FD);
1943   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944   switch (FES) {
1945   case FunctionEmissionStatus::Emitted:
1946     Kind = SemaDiagnosticBuilder::K_Immediate;
1947     break;
1948   case FunctionEmissionStatus::Unknown:
1949     Kind = SemaDiagnosticBuilder::K_Deferred;
1950     break;
1951   case FunctionEmissionStatus::TemplateDiscarded:
1952   case FunctionEmissionStatus::OMPDiscarded:
1953   case FunctionEmissionStatus::CUDADiscarded:
1954     Kind = SemaDiagnosticBuilder::K_Nop;
1955     break;
1956   }
1957 
1958   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1959 }
1960 
1961 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)1962 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1963   if (LO.OpenMP <= 45) {
1964     if (VD->getType().getNonReferenceType()->isScalarType())
1965       return OMPC_DEFAULTMAP_scalar;
1966     return OMPC_DEFAULTMAP_aggregate;
1967   }
1968   if (VD->getType().getNonReferenceType()->isAnyPointerType())
1969     return OMPC_DEFAULTMAP_pointer;
1970   if (VD->getType().getNonReferenceType()->isScalarType())
1971     return OMPC_DEFAULTMAP_scalar;
1972   return OMPC_DEFAULTMAP_aggregate;
1973 }
1974 
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const1975 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1976                                  unsigned OpenMPCaptureLevel) const {
1977   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1978 
1979   ASTContext &Ctx = getASTContext();
1980   bool IsByRef = true;
1981 
1982   // Find the directive that is associated with the provided scope.
1983   D = cast<ValueDecl>(D->getCanonicalDecl());
1984   QualType Ty = D->getType();
1985 
1986   bool IsVariableUsedInMapClause = false;
1987   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1988     // This table summarizes how a given variable should be passed to the device
1989     // given its type and the clauses where it appears. This table is based on
1990     // the description in OpenMP 4.5 [2.10.4, target Construct] and
1991     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1992     //
1993     // =========================================================================
1994     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
1995     // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
1996     // =========================================================================
1997     // | scl  |               |     |       |       -       |          | bycopy|
1998     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
1999     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2000     // | scl  |       x       |     |       |       -       |          | byref |
2001     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2002     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2003     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2004     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2005     //
2006     // | agg  |      n.a.     |     |       |       -       |          | byref |
2007     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2008     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2009     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2010     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2011     //
2012     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2013     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2014     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2015     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2016     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2017     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2018     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2019     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2020     // =========================================================================
2021     // Legend:
2022     //  scl - scalar
2023     //  ptr - pointer
2024     //  agg - aggregate
2025     //  x - applies
2026     //  - - invalid in this combination
2027     //  [] - mapped with an array section
2028     //  byref - should be mapped by reference
2029     //  byval - should be mapped by value
2030     //  null - initialize a local variable to null on the device
2031     //
2032     // Observations:
2033     //  - All scalar declarations that show up in a map clause have to be passed
2034     //    by reference, because they may have been mapped in the enclosing data
2035     //    environment.
2036     //  - If the scalar value does not fit the size of uintptr, it has to be
2037     //    passed by reference, regardless the result in the table above.
2038     //  - For pointers mapped by value that have either an implicit map or an
2039     //    array section, the runtime library may pass the NULL value to the
2040     //    device instead of the value passed to it by the compiler.
2041 
2042     if (Ty->isReferenceType())
2043       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2044 
2045     // Locate map clauses and see if the variable being captured is referred to
2046     // in any of those clauses. Here we only care about variables, not fields,
2047     // because fields are part of aggregates.
2048     bool IsVariableAssociatedWithSection = false;
2049 
2050     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2051         D, Level,
2052         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2053             OMPClauseMappableExprCommon::MappableExprComponentListRef
2054                 MapExprComponents,
2055             OpenMPClauseKind WhereFoundClauseKind) {
2056           // Only the map clause information influences how a variable is
2057           // captured. E.g. is_device_ptr does not require changing the default
2058           // behavior.
2059           if (WhereFoundClauseKind != OMPC_map)
2060             return false;
2061 
2062           auto EI = MapExprComponents.rbegin();
2063           auto EE = MapExprComponents.rend();
2064 
2065           assert(EI != EE && "Invalid map expression!");
2066 
2067           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2068             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2069 
2070           ++EI;
2071           if (EI == EE)
2072             return false;
2073 
2074           if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2075               isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2076               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2077               isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2078             IsVariableAssociatedWithSection = true;
2079             // There is nothing more we need to know about this variable.
2080             return true;
2081           }
2082 
2083           // Keep looking for more map info.
2084           return false;
2085         });
2086 
2087     if (IsVariableUsedInMapClause) {
2088       // If variable is identified in a map clause it is always captured by
2089       // reference except if it is a pointer that is dereferenced somehow.
2090       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2091     } else {
2092       // By default, all the data that has a scalar type is mapped by copy
2093       // (except for reduction variables).
2094       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2095       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2096                  !Ty->isAnyPointerType()) ||
2097                 !Ty->isScalarType() ||
2098                 DSAStack->isDefaultmapCapturedByRef(
2099                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2100                 DSAStack->hasExplicitDSA(
2101                     D,
2102                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2103                       return K == OMPC_reduction && !AppliedToPointee;
2104                     },
2105                     Level);
2106     }
2107   }
2108 
2109   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2110     IsByRef =
2111         ((IsVariableUsedInMapClause &&
2112           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2113               OMPD_target) ||
2114          !(DSAStack->hasExplicitDSA(
2115                D,
2116                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2117                  return K == OMPC_firstprivate ||
2118                         (K == OMPC_reduction && AppliedToPointee);
2119                },
2120                Level, /*NotLastprivate=*/true) ||
2121            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2122         // If the variable is artificial and must be captured by value - try to
2123         // capture by value.
2124         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2125           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2126         // If the variable is implicitly firstprivate and scalar - capture by
2127         // copy
2128         !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2129           !DSAStack->hasExplicitDSA(
2130               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2131               Level) &&
2132           !DSAStack->isLoopControlVariable(D, Level).first);
2133   }
2134 
2135   // When passing data by copy, we need to make sure it fits the uintptr size
2136   // and alignment, because the runtime library only deals with uintptr types.
2137   // If it does not fit the uintptr size, we need to pass the data by reference
2138   // instead.
2139   if (!IsByRef &&
2140       (Ctx.getTypeSizeInChars(Ty) >
2141            Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2142        Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2143     IsByRef = true;
2144   }
2145 
2146   return IsByRef;
2147 }
2148 
getOpenMPNestingLevel() const2149 unsigned Sema::getOpenMPNestingLevel() const {
2150   assert(getLangOpts().OpenMP);
2151   return DSAStack->getNestingLevel();
2152 }
2153 
isInOpenMPTargetExecutionDirective() const2154 bool Sema::isInOpenMPTargetExecutionDirective() const {
2155   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2156           !DSAStack->isClauseParsingMode()) ||
2157          DSAStack->hasDirective(
2158              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2159                 SourceLocation) -> bool {
2160                return isOpenMPTargetExecutionDirective(K);
2161              },
2162              false);
2163 }
2164 
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2165 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2166                                     unsigned StopAt) {
2167   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2168   D = getCanonicalDecl(D);
2169 
2170   auto *VD = dyn_cast<VarDecl>(D);
2171   // Do not capture constexpr variables.
2172   if (VD && VD->isConstexpr())
2173     return nullptr;
2174 
2175   // If we want to determine whether the variable should be captured from the
2176   // perspective of the current capturing scope, and we've already left all the
2177   // capturing scopes of the top directive on the stack, check from the
2178   // perspective of its parent directive (if any) instead.
2179   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2180       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2181 
2182   // If we are attempting to capture a global variable in a directive with
2183   // 'target' we return true so that this global is also mapped to the device.
2184   //
2185   if (VD && !VD->hasLocalStorage() &&
2186       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2187     if (isInOpenMPDeclareTargetContext()) {
2188       // Try to mark variable as declare target if it is used in capturing
2189       // regions.
2190       if (LangOpts.OpenMP <= 45 &&
2191           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2193       return nullptr;
2194     }
2195     if (isInOpenMPTargetExecutionDirective()) {
2196       // If the declaration is enclosed in a 'declare target' directive,
2197       // then it should not be captured.
2198       //
2199       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2200         return nullptr;
2201       CapturedRegionScopeInfo *CSI = nullptr;
2202       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2203                llvm::reverse(FunctionScopes),
2204                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2205         if (!isa<CapturingScopeInfo>(FSI))
2206           return nullptr;
2207         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2208           if (RSI->CapRegionKind == CR_OpenMP) {
2209             CSI = RSI;
2210             break;
2211           }
2212       }
2213       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2214       SmallVector<OpenMPDirectiveKind, 4> Regions;
2215       getOpenMPCaptureRegions(Regions,
2216                               DSAStack->getDirective(CSI->OpenMPLevel));
2217       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2218         return VD;
2219     }
2220   }
2221 
2222   if (CheckScopeInfo) {
2223     bool OpenMPFound = false;
2224     for (unsigned I = StopAt + 1; I > 0; --I) {
2225       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2226       if(!isa<CapturingScopeInfo>(FSI))
2227         return nullptr;
2228       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2229         if (RSI->CapRegionKind == CR_OpenMP) {
2230           OpenMPFound = true;
2231           break;
2232         }
2233     }
2234     if (!OpenMPFound)
2235       return nullptr;
2236   }
2237 
2238   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2239       (!DSAStack->isClauseParsingMode() ||
2240        DSAStack->getParentDirective() != OMPD_unknown)) {
2241     auto &&Info = DSAStack->isLoopControlVariable(D);
2242     if (Info.first ||
2243         (VD && VD->hasLocalStorage() &&
2244          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2245         (VD && DSAStack->isForceVarCapturing()))
2246       return VD ? VD : Info.second;
2247     DSAStackTy::DSAVarData DVarTop =
2248         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2249     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2250         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2251       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2252     // Threadprivate variables must not be captured.
2253     if (isOpenMPThreadPrivate(DVarTop.CKind))
2254       return nullptr;
2255     // The variable is not private or it is the variable in the directive with
2256     // default(none) clause and not used in any clause.
2257     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2258         D,
2259         [](OpenMPClauseKind C, bool AppliedToPointee) {
2260           return isOpenMPPrivate(C) && !AppliedToPointee;
2261         },
2262         [](OpenMPDirectiveKind) { return true; },
2263         DSAStack->isClauseParsingMode());
2264     // Global shared must not be captured.
2265     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2266         ((DSAStack->getDefaultDSA() != DSA_none &&
2267           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2268          DVarTop.CKind == OMPC_shared))
2269       return nullptr;
2270     if (DVarPrivate.CKind != OMPC_unknown ||
2271         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2272                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2273       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2274   }
2275   return nullptr;
2276 }
2277 
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2278 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2279                                         unsigned Level) const {
2280   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2281 }
2282 
startOpenMPLoop()2283 void Sema::startOpenMPLoop() {
2284   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2285   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2286     DSAStack->loopInit();
2287 }
2288 
startOpenMPCXXRangeFor()2289 void Sema::startOpenMPCXXRangeFor() {
2290   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2291   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2292     DSAStack->resetPossibleLoopCounter();
2293     DSAStack->loopStart();
2294   }
2295 }
2296 
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2297 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2298                                            unsigned CapLevel) const {
2299   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2300   if (DSAStack->hasExplicitDirective(
2301           [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2302           Level)) {
2303     bool IsTriviallyCopyable =
2304         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2305         !D->getType()
2306              .getNonReferenceType()
2307              .getCanonicalType()
2308              ->getAsCXXRecordDecl();
2309     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2310     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2311     getOpenMPCaptureRegions(CaptureRegions, DKind);
2312     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2313         (IsTriviallyCopyable ||
2314          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2315       if (DSAStack->hasExplicitDSA(
2316               D,
2317               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2318               Level, /*NotLastprivate=*/true))
2319         return OMPC_firstprivate;
2320       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2321       if (DVar.CKind != OMPC_shared &&
2322           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2323         DSAStack->addImplicitTaskFirstprivate(Level, D);
2324         return OMPC_firstprivate;
2325       }
2326     }
2327   }
2328   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2329     if (DSAStack->getAssociatedLoops() > 0 &&
2330         !DSAStack->isLoopStarted()) {
2331       DSAStack->resetPossibleLoopCounter(D);
2332       DSAStack->loopStart();
2333       return OMPC_private;
2334     }
2335     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2336          DSAStack->isLoopControlVariable(D).first) &&
2337         !DSAStack->hasExplicitDSA(
2338             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2339             Level) &&
2340         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2341       return OMPC_private;
2342   }
2343   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2344     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2345         DSAStack->isForceVarCapturing() &&
2346         !DSAStack->hasExplicitDSA(
2347             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2348             Level))
2349       return OMPC_private;
2350   }
2351   // User-defined allocators are private since they must be defined in the
2352   // context of target region.
2353   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2354       DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2355           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2356           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2357     return OMPC_private;
2358   return (DSAStack->hasExplicitDSA(
2359               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2360               Level) ||
2361           (DSAStack->isClauseParsingMode() &&
2362            DSAStack->getClauseParsingMode() == OMPC_private) ||
2363           // Consider taskgroup reduction descriptor variable a private
2364           // to avoid possible capture in the region.
2365           (DSAStack->hasExplicitDirective(
2366                [](OpenMPDirectiveKind K) {
2367                  return K == OMPD_taskgroup ||
2368                         ((isOpenMPParallelDirective(K) ||
2369                           isOpenMPWorksharingDirective(K)) &&
2370                          !isOpenMPSimdDirective(K));
2371                },
2372                Level) &&
2373            DSAStack->isTaskgroupReductionRef(D, Level)))
2374              ? OMPC_private
2375              : OMPC_unknown;
2376 }
2377 
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2378 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2379                                 unsigned Level) {
2380   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2381   D = getCanonicalDecl(D);
2382   OpenMPClauseKind OMPC = OMPC_unknown;
2383   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2384     const unsigned NewLevel = I - 1;
2385     if (DSAStack->hasExplicitDSA(
2386             D,
2387             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2388               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2389                 OMPC = K;
2390                 return true;
2391               }
2392               return false;
2393             },
2394             NewLevel))
2395       break;
2396     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2397             D, NewLevel,
2398             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2399                OpenMPClauseKind) { return true; })) {
2400       OMPC = OMPC_map;
2401       break;
2402     }
2403     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2404                                        NewLevel)) {
2405       OMPC = OMPC_map;
2406       if (DSAStack->mustBeFirstprivateAtLevel(
2407               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2408         OMPC = OMPC_firstprivate;
2409       break;
2410     }
2411   }
2412   if (OMPC != OMPC_unknown)
2413     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2414 }
2415 
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2416 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2417                                       unsigned CaptureLevel) const {
2418   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2419   // Return true if the current level is no longer enclosed in a target region.
2420 
2421   SmallVector<OpenMPDirectiveKind, 4> Regions;
2422   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2423   const auto *VD = dyn_cast<VarDecl>(D);
2424   return VD && !VD->hasLocalStorage() &&
2425          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2426                                         Level) &&
2427          Regions[CaptureLevel] != OMPD_task;
2428 }
2429 
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2430 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2431                                       unsigned CaptureLevel) const {
2432   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2433   // Return true if the current level is no longer enclosed in a target region.
2434 
2435   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2436     if (!VD->hasLocalStorage()) {
2437       if (isInOpenMPTargetExecutionDirective())
2438         return true;
2439       DSAStackTy::DSAVarData TopDVar =
2440           DSAStack->getTopDSA(D, /*FromParent=*/false);
2441       unsigned NumLevels =
2442           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2443       if (Level == 0)
2444         return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2445       do {
2446         --Level;
2447         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2448         if (DVar.CKind != OMPC_shared)
2449           return true;
2450       } while (Level > 0);
2451     }
2452   }
2453   return true;
2454 }
2455 
DestroyDataSharingAttributesStack()2456 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2457 
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2458 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2459                                           OMPTraitInfo &TI) {
2460   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2461 }
2462 
ActOnOpenMPEndDeclareVariant()2463 void Sema::ActOnOpenMPEndDeclareVariant() {
2464   assert(isInOpenMPDeclareVariantScope() &&
2465          "Not in OpenMP declare variant scope!");
2466 
2467   OMPDeclareVariantScopes.pop_back();
2468 }
2469 
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2470 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2471                                          const FunctionDecl *Callee,
2472                                          SourceLocation Loc) {
2473   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2474   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2475       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2476   // Ignore host functions during device analyzis.
2477   if (LangOpts.OpenMPIsDevice && DevTy &&
2478       *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2479     return;
2480   // Ignore nohost functions during host analyzis.
2481   if (!LangOpts.OpenMPIsDevice && DevTy &&
2482       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2483     return;
2484   const FunctionDecl *FD = Callee->getMostRecentDecl();
2485   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2486   if (LangOpts.OpenMPIsDevice && DevTy &&
2487       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2488     // Diagnose host function called during device codegen.
2489     StringRef HostDevTy =
2490         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2491     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2492     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2493          diag::note_omp_marked_device_type_here)
2494         << HostDevTy;
2495     return;
2496   }
2497       if (!LangOpts.OpenMPIsDevice && DevTy &&
2498           *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2499         // Diagnose nohost function called during host codegen.
2500         StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2501             OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2502         Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2503         Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2504              diag::note_omp_marked_device_type_here)
2505             << NoHostDevTy;
2506       }
2507 }
2508 
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2509 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2510                                const DeclarationNameInfo &DirName,
2511                                Scope *CurScope, SourceLocation Loc) {
2512   DSAStack->push(DKind, DirName, CurScope, Loc);
2513   PushExpressionEvaluationContext(
2514       ExpressionEvaluationContext::PotentiallyEvaluated);
2515 }
2516 
StartOpenMPClause(OpenMPClauseKind K)2517 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2518   DSAStack->setClauseParsingMode(K);
2519 }
2520 
EndOpenMPClause()2521 void Sema::EndOpenMPClause() {
2522   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2523 }
2524 
2525 static std::pair<ValueDecl *, bool>
2526 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2527                SourceRange &ERange, bool AllowArraySection = false);
2528 
2529 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2530 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2531                                   ArrayRef<OMPClause *> Clauses) {
2532   bool InscanFound = false;
2533   SourceLocation InscanLoc;
2534   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2535   // A reduction clause without the inscan reduction-modifier may not appear on
2536   // a construct on which a reduction clause with the inscan reduction-modifier
2537   // appears.
2538   for (OMPClause *C : Clauses) {
2539     if (C->getClauseKind() != OMPC_reduction)
2540       continue;
2541     auto *RC = cast<OMPReductionClause>(C);
2542     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2543       InscanFound = true;
2544       InscanLoc = RC->getModifierLoc();
2545       continue;
2546     }
2547     if (RC->getModifier() == OMPC_REDUCTION_task) {
2548       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2549       // A reduction clause with the task reduction-modifier may only appear on
2550       // a parallel construct, a worksharing construct or a combined or
2551       // composite construct for which any of the aforementioned constructs is a
2552       // constituent construct and simd or loop are not constituent constructs.
2553       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2554       if (!(isOpenMPParallelDirective(CurDir) ||
2555             isOpenMPWorksharingDirective(CurDir)) ||
2556           isOpenMPSimdDirective(CurDir))
2557         S.Diag(RC->getModifierLoc(),
2558                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2559       continue;
2560     }
2561   }
2562   if (InscanFound) {
2563     for (OMPClause *C : Clauses) {
2564       if (C->getClauseKind() != OMPC_reduction)
2565         continue;
2566       auto *RC = cast<OMPReductionClause>(C);
2567       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2568         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2569                    ? RC->getBeginLoc()
2570                    : RC->getModifierLoc(),
2571                diag::err_omp_inscan_reduction_expected);
2572         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2573         continue;
2574       }
2575       for (Expr *Ref : RC->varlists()) {
2576         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2577         SourceLocation ELoc;
2578         SourceRange ERange;
2579         Expr *SimpleRefExpr = Ref;
2580         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2581                                   /*AllowArraySection=*/true);
2582         ValueDecl *D = Res.first;
2583         if (!D)
2584           continue;
2585         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2586           S.Diag(Ref->getExprLoc(),
2587                  diag::err_omp_reduction_not_inclusive_exclusive)
2588               << Ref->getSourceRange();
2589         }
2590       }
2591     }
2592   }
2593 }
2594 
2595 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2596                                  ArrayRef<OMPClause *> Clauses);
2597 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2598                                  bool WithInit);
2599 
2600 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2601                               const ValueDecl *D,
2602                               const DSAStackTy::DSAVarData &DVar,
2603                               bool IsLoopIterVar = false);
2604 
EndOpenMPDSABlock(Stmt * CurDirective)2605 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2606   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2607   //  A variable of class type (or array thereof) that appears in a lastprivate
2608   //  clause requires an accessible, unambiguous default constructor for the
2609   //  class type, unless the list item is also specified in a firstprivate
2610   //  clause.
2611   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2612     for (OMPClause *C : D->clauses()) {
2613       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2614         SmallVector<Expr *, 8> PrivateCopies;
2615         for (Expr *DE : Clause->varlists()) {
2616           if (DE->isValueDependent() || DE->isTypeDependent()) {
2617             PrivateCopies.push_back(nullptr);
2618             continue;
2619           }
2620           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2621           auto *VD = cast<VarDecl>(DRE->getDecl());
2622           QualType Type = VD->getType().getNonReferenceType();
2623           const DSAStackTy::DSAVarData DVar =
2624               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2625           if (DVar.CKind == OMPC_lastprivate) {
2626             // Generate helper private variable and initialize it with the
2627             // default value. The address of the original variable is replaced
2628             // by the address of the new private variable in CodeGen. This new
2629             // variable is not added to IdResolver, so the code in the OpenMP
2630             // region uses original variable for proper diagnostics.
2631             VarDecl *VDPrivate = buildVarDecl(
2632                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2633                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2634             ActOnUninitializedDecl(VDPrivate);
2635             if (VDPrivate->isInvalidDecl()) {
2636               PrivateCopies.push_back(nullptr);
2637               continue;
2638             }
2639             PrivateCopies.push_back(buildDeclRefExpr(
2640                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2641           } else {
2642             // The variable is also a firstprivate, so initialization sequence
2643             // for private copy is generated already.
2644             PrivateCopies.push_back(nullptr);
2645           }
2646         }
2647         Clause->setPrivateCopies(PrivateCopies);
2648         continue;
2649       }
2650       // Finalize nontemporal clause by handling private copies, if any.
2651       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2652         SmallVector<Expr *, 8> PrivateRefs;
2653         for (Expr *RefExpr : Clause->varlists()) {
2654           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2655           SourceLocation ELoc;
2656           SourceRange ERange;
2657           Expr *SimpleRefExpr = RefExpr;
2658           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2659           if (Res.second)
2660             // It will be analyzed later.
2661             PrivateRefs.push_back(RefExpr);
2662           ValueDecl *D = Res.first;
2663           if (!D)
2664             continue;
2665 
2666           const DSAStackTy::DSAVarData DVar =
2667               DSAStack->getTopDSA(D, /*FromParent=*/false);
2668           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2669                                                  : SimpleRefExpr);
2670         }
2671         Clause->setPrivateRefs(PrivateRefs);
2672         continue;
2673       }
2674       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2675         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2676           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2677           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2678           if (!DRE)
2679             continue;
2680           ValueDecl *VD = DRE->getDecl();
2681           if (!VD || !isa<VarDecl>(VD))
2682             continue;
2683           DSAStackTy::DSAVarData DVar =
2684               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2685           // OpenMP [2.12.5, target Construct]
2686           // Memory allocators that appear in a uses_allocators clause cannot
2687           // appear in other data-sharing attribute clauses or data-mapping
2688           // attribute clauses in the same construct.
2689           Expr *MapExpr = nullptr;
2690           if (DVar.RefExpr ||
2691               DSAStack->checkMappableExprComponentListsForDecl(
2692                   VD, /*CurrentRegionOnly=*/true,
2693                   [VD, &MapExpr](
2694                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2695                           MapExprComponents,
2696                       OpenMPClauseKind C) {
2697                     auto MI = MapExprComponents.rbegin();
2698                     auto ME = MapExprComponents.rend();
2699                     if (MI != ME &&
2700                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2701                             VD->getCanonicalDecl()) {
2702                       MapExpr = MI->getAssociatedExpression();
2703                       return true;
2704                     }
2705                     return false;
2706                   })) {
2707             Diag(D.Allocator->getExprLoc(),
2708                  diag::err_omp_allocator_used_in_clauses)
2709                 << D.Allocator->getSourceRange();
2710             if (DVar.RefExpr)
2711               reportOriginalDsa(*this, DSAStack, VD, DVar);
2712             else
2713               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2714                   << MapExpr->getSourceRange();
2715           }
2716         }
2717         continue;
2718       }
2719     }
2720     // Check allocate clauses.
2721     if (!CurContext->isDependentContext())
2722       checkAllocateClauses(*this, DSAStack, D->clauses());
2723     checkReductionClauses(*this, DSAStack, D->clauses());
2724   }
2725 
2726   DSAStack->pop();
2727   DiscardCleanupsInEvaluationContext();
2728   PopExpressionEvaluationContext();
2729 }
2730 
2731 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2732                                      Expr *NumIterations, Sema &SemaRef,
2733                                      Scope *S, DSAStackTy *Stack);
2734 
2735 namespace {
2736 
2737 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2738 private:
2739   Sema &SemaRef;
2740 
2741 public:
VarDeclFilterCCC(Sema & S)2742   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2743   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2744     NamedDecl *ND = Candidate.getCorrectionDecl();
2745     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2746       return VD->hasGlobalStorage() &&
2747              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2748                                    SemaRef.getCurScope());
2749     }
2750     return false;
2751   }
2752 
clone()2753   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2754     return std::make_unique<VarDeclFilterCCC>(*this);
2755   }
2756 
2757 };
2758 
2759 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2760 private:
2761   Sema &SemaRef;
2762 
2763 public:
VarOrFuncDeclFilterCCC(Sema & S)2764   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2765   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2766     NamedDecl *ND = Candidate.getCorrectionDecl();
2767     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2768                isa<FunctionDecl>(ND))) {
2769       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2770                                    SemaRef.getCurScope());
2771     }
2772     return false;
2773   }
2774 
clone()2775   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2776     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2777   }
2778 };
2779 
2780 } // namespace
2781 
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2782 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2783                                          CXXScopeSpec &ScopeSpec,
2784                                          const DeclarationNameInfo &Id,
2785                                          OpenMPDirectiveKind Kind) {
2786   LookupResult Lookup(*this, Id, LookupOrdinaryName);
2787   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2788 
2789   if (Lookup.isAmbiguous())
2790     return ExprError();
2791 
2792   VarDecl *VD;
2793   if (!Lookup.isSingleResult()) {
2794     VarDeclFilterCCC CCC(*this);
2795     if (TypoCorrection Corrected =
2796             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2797                         CTK_ErrorRecovery)) {
2798       diagnoseTypo(Corrected,
2799                    PDiag(Lookup.empty()
2800                              ? diag::err_undeclared_var_use_suggest
2801                              : diag::err_omp_expected_var_arg_suggest)
2802                        << Id.getName());
2803       VD = Corrected.getCorrectionDeclAs<VarDecl>();
2804     } else {
2805       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2806                                        : diag::err_omp_expected_var_arg)
2807           << Id.getName();
2808       return ExprError();
2809     }
2810   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2811     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2812     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2813     return ExprError();
2814   }
2815   Lookup.suppressDiagnostics();
2816 
2817   // OpenMP [2.9.2, Syntax, C/C++]
2818   //   Variables must be file-scope, namespace-scope, or static block-scope.
2819   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2820     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2821         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2822     bool IsDecl =
2823         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2824     Diag(VD->getLocation(),
2825          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2826         << VD;
2827     return ExprError();
2828   }
2829 
2830   VarDecl *CanonicalVD = VD->getCanonicalDecl();
2831   NamedDecl *ND = CanonicalVD;
2832   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2833   //   A threadprivate directive for file-scope variables must appear outside
2834   //   any definition or declaration.
2835   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2836       !getCurLexicalContext()->isTranslationUnit()) {
2837     Diag(Id.getLoc(), diag::err_omp_var_scope)
2838         << getOpenMPDirectiveName(Kind) << VD;
2839     bool IsDecl =
2840         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2841     Diag(VD->getLocation(),
2842          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2843         << VD;
2844     return ExprError();
2845   }
2846   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2847   //   A threadprivate directive for static class member variables must appear
2848   //   in the class definition, in the same scope in which the member
2849   //   variables are declared.
2850   if (CanonicalVD->isStaticDataMember() &&
2851       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2852     Diag(Id.getLoc(), diag::err_omp_var_scope)
2853         << getOpenMPDirectiveName(Kind) << VD;
2854     bool IsDecl =
2855         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2856     Diag(VD->getLocation(),
2857          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2858         << VD;
2859     return ExprError();
2860   }
2861   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2862   //   A threadprivate directive for namespace-scope variables must appear
2863   //   outside any definition or declaration other than the namespace
2864   //   definition itself.
2865   if (CanonicalVD->getDeclContext()->isNamespace() &&
2866       (!getCurLexicalContext()->isFileContext() ||
2867        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2868     Diag(Id.getLoc(), diag::err_omp_var_scope)
2869         << getOpenMPDirectiveName(Kind) << VD;
2870     bool IsDecl =
2871         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2872     Diag(VD->getLocation(),
2873          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2874         << VD;
2875     return ExprError();
2876   }
2877   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2878   //   A threadprivate directive for static block-scope variables must appear
2879   //   in the scope of the variable and not in a nested scope.
2880   if (CanonicalVD->isLocalVarDecl() && CurScope &&
2881       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2882     Diag(Id.getLoc(), diag::err_omp_var_scope)
2883         << getOpenMPDirectiveName(Kind) << VD;
2884     bool IsDecl =
2885         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2886     Diag(VD->getLocation(),
2887          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2888         << VD;
2889     return ExprError();
2890   }
2891 
2892   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2893   //   A threadprivate directive must lexically precede all references to any
2894   //   of the variables in its list.
2895   if (Kind == OMPD_threadprivate && VD->isUsed() &&
2896       !DSAStack->isThreadPrivate(VD)) {
2897     Diag(Id.getLoc(), diag::err_omp_var_used)
2898         << getOpenMPDirectiveName(Kind) << VD;
2899     return ExprError();
2900   }
2901 
2902   QualType ExprType = VD->getType().getNonReferenceType();
2903   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2904                              SourceLocation(), VD,
2905                              /*RefersToEnclosingVariableOrCapture=*/false,
2906                              Id.getLoc(), ExprType, VK_LValue);
2907 }
2908 
2909 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)2910 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2911                                         ArrayRef<Expr *> VarList) {
2912   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2913     CurContext->addDecl(D);
2914     return DeclGroupPtrTy::make(DeclGroupRef(D));
2915   }
2916   return nullptr;
2917 }
2918 
2919 namespace {
2920 class LocalVarRefChecker final
2921     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2922   Sema &SemaRef;
2923 
2924 public:
VisitDeclRefExpr(const DeclRefExpr * E)2925   bool VisitDeclRefExpr(const DeclRefExpr *E) {
2926     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2927       if (VD->hasLocalStorage()) {
2928         SemaRef.Diag(E->getBeginLoc(),
2929                      diag::err_omp_local_var_in_threadprivate_init)
2930             << E->getSourceRange();
2931         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2932             << VD << VD->getSourceRange();
2933         return true;
2934       }
2935     }
2936     return false;
2937   }
VisitStmt(const Stmt * S)2938   bool VisitStmt(const Stmt *S) {
2939     for (const Stmt *Child : S->children()) {
2940       if (Child && Visit(Child))
2941         return true;
2942     }
2943     return false;
2944   }
LocalVarRefChecker(Sema & SemaRef)2945   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2946 };
2947 } // namespace
2948 
2949 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2950 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2951   SmallVector<Expr *, 8> Vars;
2952   for (Expr *RefExpr : VarList) {
2953     auto *DE = cast<DeclRefExpr>(RefExpr);
2954     auto *VD = cast<VarDecl>(DE->getDecl());
2955     SourceLocation ILoc = DE->getExprLoc();
2956 
2957     // Mark variable as used.
2958     VD->setReferenced();
2959     VD->markUsed(Context);
2960 
2961     QualType QType = VD->getType();
2962     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2963       // It will be analyzed later.
2964       Vars.push_back(DE);
2965       continue;
2966     }
2967 
2968     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2969     //   A threadprivate variable must not have an incomplete type.
2970     if (RequireCompleteType(ILoc, VD->getType(),
2971                             diag::err_omp_threadprivate_incomplete_type)) {
2972       continue;
2973     }
2974 
2975     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2976     //   A threadprivate variable must not have a reference type.
2977     if (VD->getType()->isReferenceType()) {
2978       Diag(ILoc, diag::err_omp_ref_type_arg)
2979           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2980       bool IsDecl =
2981           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2982       Diag(VD->getLocation(),
2983            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2984           << VD;
2985       continue;
2986     }
2987 
2988     // Check if this is a TLS variable. If TLS is not being supported, produce
2989     // the corresponding diagnostic.
2990     if ((VD->getTLSKind() != VarDecl::TLS_None &&
2991          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2992            getLangOpts().OpenMPUseTLS &&
2993            getASTContext().getTargetInfo().isTLSSupported())) ||
2994         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2995          !VD->isLocalVarDecl())) {
2996       Diag(ILoc, diag::err_omp_var_thread_local)
2997           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2998       bool IsDecl =
2999           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3000       Diag(VD->getLocation(),
3001            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3002           << VD;
3003       continue;
3004     }
3005 
3006     // Check if initial value of threadprivate variable reference variable with
3007     // local storage (it is not supported by runtime).
3008     if (const Expr *Init = VD->getAnyInitializer()) {
3009       LocalVarRefChecker Checker(*this);
3010       if (Checker.Visit(Init))
3011         continue;
3012     }
3013 
3014     Vars.push_back(RefExpr);
3015     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3016     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3017         Context, SourceRange(Loc, Loc)));
3018     if (ASTMutationListener *ML = Context.getASTMutationListener())
3019       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3020   }
3021   OMPThreadPrivateDecl *D = nullptr;
3022   if (!Vars.empty()) {
3023     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3024                                      Vars);
3025     D->setAccess(AS_public);
3026   }
3027   return D;
3028 }
3029 
3030 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3031 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3032   if (!Allocator)
3033     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3034   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3035       Allocator->isInstantiationDependent() ||
3036       Allocator->containsUnexpandedParameterPack())
3037     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3038   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3039   const Expr *AE = Allocator->IgnoreParenImpCasts();
3040   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3041     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3042     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3043     llvm::FoldingSetNodeID AEId, DAEId;
3044     AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3045     DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3046     if (AEId == DAEId) {
3047       AllocatorKindRes = AllocatorKind;
3048       break;
3049     }
3050   }
3051   return AllocatorKindRes;
3052 }
3053 
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3054 static bool checkPreviousOMPAllocateAttribute(
3055     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3056     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3057   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3058     return false;
3059   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3060   Expr *PrevAllocator = A->getAllocator();
3061   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3062       getAllocatorKind(S, Stack, PrevAllocator);
3063   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3064   if (AllocatorsMatch &&
3065       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3066       Allocator && PrevAllocator) {
3067     const Expr *AE = Allocator->IgnoreParenImpCasts();
3068     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3069     llvm::FoldingSetNodeID AEId, PAEId;
3070     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3071     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3072     AllocatorsMatch = AEId == PAEId;
3073   }
3074   if (!AllocatorsMatch) {
3075     SmallString<256> AllocatorBuffer;
3076     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3077     if (Allocator)
3078       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3079     SmallString<256> PrevAllocatorBuffer;
3080     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3081     if (PrevAllocator)
3082       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3083                                  S.getPrintingPolicy());
3084 
3085     SourceLocation AllocatorLoc =
3086         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3087     SourceRange AllocatorRange =
3088         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3089     SourceLocation PrevAllocatorLoc =
3090         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3091     SourceRange PrevAllocatorRange =
3092         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3093     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3094         << (Allocator ? 1 : 0) << AllocatorStream.str()
3095         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3096         << AllocatorRange;
3097     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3098         << PrevAllocatorRange;
3099     return true;
3100   }
3101   return false;
3102 }
3103 
3104 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,SourceRange SR)3105 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3106                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3107                           Expr *Allocator, SourceRange SR) {
3108   if (VD->hasAttr<OMPAllocateDeclAttr>())
3109     return;
3110   if (Allocator &&
3111       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3112        Allocator->isInstantiationDependent() ||
3113        Allocator->containsUnexpandedParameterPack()))
3114     return;
3115   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3116                                                 Allocator, SR);
3117   VD->addAttr(A);
3118   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3119     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3120 }
3121 
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3122 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3123     SourceLocation Loc, ArrayRef<Expr *> VarList,
3124     ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3125   assert(Clauses.size() <= 1 && "Expected at most one clause.");
3126   Expr *Allocator = nullptr;
3127   if (Clauses.empty()) {
3128     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3129     // allocate directives that appear in a target region must specify an
3130     // allocator clause unless a requires directive with the dynamic_allocators
3131     // clause is present in the same compilation unit.
3132     if (LangOpts.OpenMPIsDevice &&
3133         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3134       targetDiag(Loc, diag::err_expected_allocator_clause);
3135   } else {
3136     Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3137   }
3138   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3139       getAllocatorKind(*this, DSAStack, Allocator);
3140   SmallVector<Expr *, 8> Vars;
3141   for (Expr *RefExpr : VarList) {
3142     auto *DE = cast<DeclRefExpr>(RefExpr);
3143     auto *VD = cast<VarDecl>(DE->getDecl());
3144 
3145     // Check if this is a TLS variable or global register.
3146     if (VD->getTLSKind() != VarDecl::TLS_None ||
3147         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3148         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3149          !VD->isLocalVarDecl()))
3150       continue;
3151 
3152     // If the used several times in the allocate directive, the same allocator
3153     // must be used.
3154     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3155                                           AllocatorKind, Allocator))
3156       continue;
3157 
3158     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3159     // If a list item has a static storage type, the allocator expression in the
3160     // allocator clause must be a constant expression that evaluates to one of
3161     // the predefined memory allocator values.
3162     if (Allocator && VD->hasGlobalStorage()) {
3163       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3164         Diag(Allocator->getExprLoc(),
3165              diag::err_omp_expected_predefined_allocator)
3166             << Allocator->getSourceRange();
3167         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3168                       VarDecl::DeclarationOnly;
3169         Diag(VD->getLocation(),
3170              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3171             << VD;
3172         continue;
3173       }
3174     }
3175 
3176     Vars.push_back(RefExpr);
3177     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3178                               DE->getSourceRange());
3179   }
3180   if (Vars.empty())
3181     return nullptr;
3182   if (!Owner)
3183     Owner = getCurLexicalContext();
3184   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3185   D->setAccess(AS_public);
3186   Owner->addDecl(D);
3187   return DeclGroupPtrTy::make(DeclGroupRef(D));
3188 }
3189 
3190 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3191 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3192                                    ArrayRef<OMPClause *> ClauseList) {
3193   OMPRequiresDecl *D = nullptr;
3194   if (!CurContext->isFileContext()) {
3195     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3196   } else {
3197     D = CheckOMPRequiresDecl(Loc, ClauseList);
3198     if (D) {
3199       CurContext->addDecl(D);
3200       DSAStack->addRequiresDecl(D);
3201     }
3202   }
3203   return DeclGroupPtrTy::make(DeclGroupRef(D));
3204 }
3205 
ActOnOpenMPAssumesDirective(SourceLocation Loc,OpenMPDirectiveKind DKind,ArrayRef<StringRef> Assumptions,bool SkippedClauses)3206 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3207                                        OpenMPDirectiveKind DKind,
3208                                        ArrayRef<StringRef> Assumptions,
3209                                        bool SkippedClauses) {
3210   if (!SkippedClauses && Assumptions.empty())
3211     Diag(Loc, diag::err_omp_no_clause_for_directive)
3212         << llvm::omp::getAllAssumeClauseOptions()
3213         << llvm::omp::getOpenMPDirectiveName(DKind);
3214 
3215   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3216   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3217     OMPAssumeScoped.push_back(AA);
3218     return;
3219   }
3220 
3221   // Global assumes without assumption clauses are ignored.
3222   if (Assumptions.empty())
3223     return;
3224 
3225   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3226          "Unexpected omp assumption directive!");
3227   OMPAssumeGlobal.push_back(AA);
3228 
3229   // The OMPAssumeGlobal scope above will take care of new declarations but
3230   // we also want to apply the assumption to existing ones, e.g., to
3231   // declarations in included headers. To this end, we traverse all existing
3232   // declaration contexts and annotate function declarations here.
3233   SmallVector<DeclContext *, 8> DeclContexts;
3234   auto *Ctx = CurContext;
3235   while (Ctx->getLexicalParent())
3236     Ctx = Ctx->getLexicalParent();
3237   DeclContexts.push_back(Ctx);
3238   while (!DeclContexts.empty()) {
3239     DeclContext *DC = DeclContexts.pop_back_val();
3240     for (auto *SubDC : DC->decls()) {
3241       if (SubDC->isInvalidDecl())
3242         continue;
3243       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3244         DeclContexts.push_back(CTD->getTemplatedDecl());
3245         for (auto *S : CTD->specializations())
3246           DeclContexts.push_back(S);
3247         continue;
3248       }
3249       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3250         DeclContexts.push_back(DC);
3251       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3252         F->addAttr(AA);
3253         continue;
3254       }
3255     }
3256   }
3257 }
3258 
ActOnOpenMPEndAssumesDirective()3259 void Sema::ActOnOpenMPEndAssumesDirective() {
3260   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3261   OMPAssumeScoped.pop_back();
3262 }
3263 
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3264 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3265                                             ArrayRef<OMPClause *> ClauseList) {
3266   /// For target specific clauses, the requires directive cannot be
3267   /// specified after the handling of any of the target regions in the
3268   /// current compilation unit.
3269   ArrayRef<SourceLocation> TargetLocations =
3270       DSAStack->getEncounteredTargetLocs();
3271   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3272   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3273     for (const OMPClause *CNew : ClauseList) {
3274       // Check if any of the requires clauses affect target regions.
3275       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3276           isa<OMPUnifiedAddressClause>(CNew) ||
3277           isa<OMPReverseOffloadClause>(CNew) ||
3278           isa<OMPDynamicAllocatorsClause>(CNew)) {
3279         Diag(Loc, diag::err_omp_directive_before_requires)
3280             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3281         for (SourceLocation TargetLoc : TargetLocations) {
3282           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3283               << "target";
3284         }
3285       } else if (!AtomicLoc.isInvalid() &&
3286                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3287         Diag(Loc, diag::err_omp_directive_before_requires)
3288             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3289         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3290             << "atomic";
3291       }
3292     }
3293   }
3294 
3295   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3296     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3297                                    ClauseList);
3298   return nullptr;
3299 }
3300 
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3301 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3302                               const ValueDecl *D,
3303                               const DSAStackTy::DSAVarData &DVar,
3304                               bool IsLoopIterVar) {
3305   if (DVar.RefExpr) {
3306     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3307         << getOpenMPClauseName(DVar.CKind);
3308     return;
3309   }
3310   enum {
3311     PDSA_StaticMemberShared,
3312     PDSA_StaticLocalVarShared,
3313     PDSA_LoopIterVarPrivate,
3314     PDSA_LoopIterVarLinear,
3315     PDSA_LoopIterVarLastprivate,
3316     PDSA_ConstVarShared,
3317     PDSA_GlobalVarShared,
3318     PDSA_TaskVarFirstprivate,
3319     PDSA_LocalVarPrivate,
3320     PDSA_Implicit
3321   } Reason = PDSA_Implicit;
3322   bool ReportHint = false;
3323   auto ReportLoc = D->getLocation();
3324   auto *VD = dyn_cast<VarDecl>(D);
3325   if (IsLoopIterVar) {
3326     if (DVar.CKind == OMPC_private)
3327       Reason = PDSA_LoopIterVarPrivate;
3328     else if (DVar.CKind == OMPC_lastprivate)
3329       Reason = PDSA_LoopIterVarLastprivate;
3330     else
3331       Reason = PDSA_LoopIterVarLinear;
3332   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3333              DVar.CKind == OMPC_firstprivate) {
3334     Reason = PDSA_TaskVarFirstprivate;
3335     ReportLoc = DVar.ImplicitDSALoc;
3336   } else if (VD && VD->isStaticLocal())
3337     Reason = PDSA_StaticLocalVarShared;
3338   else if (VD && VD->isStaticDataMember())
3339     Reason = PDSA_StaticMemberShared;
3340   else if (VD && VD->isFileVarDecl())
3341     Reason = PDSA_GlobalVarShared;
3342   else if (D->getType().isConstant(SemaRef.getASTContext()))
3343     Reason = PDSA_ConstVarShared;
3344   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3345     ReportHint = true;
3346     Reason = PDSA_LocalVarPrivate;
3347   }
3348   if (Reason != PDSA_Implicit) {
3349     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3350         << Reason << ReportHint
3351         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3352   } else if (DVar.ImplicitDSALoc.isValid()) {
3353     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3354         << getOpenMPClauseName(DVar.CKind);
3355   }
3356 }
3357 
3358 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3359 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3360                              bool IsAggregateOrDeclareTarget) {
3361   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3362   switch (M) {
3363   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3364     Kind = OMPC_MAP_alloc;
3365     break;
3366   case OMPC_DEFAULTMAP_MODIFIER_to:
3367     Kind = OMPC_MAP_to;
3368     break;
3369   case OMPC_DEFAULTMAP_MODIFIER_from:
3370     Kind = OMPC_MAP_from;
3371     break;
3372   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3373     Kind = OMPC_MAP_tofrom;
3374     break;
3375   case OMPC_DEFAULTMAP_MODIFIER_present:
3376     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3377     // If implicit-behavior is present, each variable referenced in the
3378     // construct in the category specified by variable-category is treated as if
3379     // it had been listed in a map clause with the map-type of alloc and
3380     // map-type-modifier of present.
3381     Kind = OMPC_MAP_alloc;
3382     break;
3383   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3384   case OMPC_DEFAULTMAP_MODIFIER_last:
3385     llvm_unreachable("Unexpected defaultmap implicit behavior");
3386   case OMPC_DEFAULTMAP_MODIFIER_none:
3387   case OMPC_DEFAULTMAP_MODIFIER_default:
3388   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3389     // IsAggregateOrDeclareTarget could be true if:
3390     // 1. the implicit behavior for aggregate is tofrom
3391     // 2. it's a declare target link
3392     if (IsAggregateOrDeclareTarget) {
3393       Kind = OMPC_MAP_tofrom;
3394       break;
3395     }
3396     llvm_unreachable("Unexpected defaultmap implicit behavior");
3397   }
3398   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3399   return Kind;
3400 }
3401 
3402 namespace {
3403 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3404   DSAStackTy *Stack;
3405   Sema &SemaRef;
3406   bool ErrorFound = false;
3407   bool TryCaptureCXXThisMembers = false;
3408   CapturedStmt *CS = nullptr;
3409   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3410   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3411   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3412   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3413       ImplicitMapModifier[DefaultmapKindNum];
3414   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3415   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3416 
VisitSubCaptures(OMPExecutableDirective * S)3417   void VisitSubCaptures(OMPExecutableDirective *S) {
3418     // Check implicitly captured variables.
3419     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3420       return;
3421     if (S->getDirectiveKind() == OMPD_atomic ||
3422         S->getDirectiveKind() == OMPD_critical ||
3423         S->getDirectiveKind() == OMPD_section ||
3424         S->getDirectiveKind() == OMPD_master) {
3425       Visit(S->getAssociatedStmt());
3426       return;
3427     }
3428     visitSubCaptures(S->getInnermostCapturedStmt());
3429     // Try to capture inner this->member references to generate correct mappings
3430     // and diagnostics.
3431     if (TryCaptureCXXThisMembers ||
3432         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3433          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3434                       [](const CapturedStmt::Capture &C) {
3435                         return C.capturesThis();
3436                       }))) {
3437       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3438       TryCaptureCXXThisMembers = true;
3439       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3440       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3441     }
3442     // In tasks firstprivates are not captured anymore, need to analyze them
3443     // explicitly.
3444     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3445         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3446       for (OMPClause *C : S->clauses())
3447         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3448           for (Expr *Ref : FC->varlists())
3449             Visit(Ref);
3450         }
3451     }
3452   }
3453 
3454 public:
VisitDeclRefExpr(DeclRefExpr * E)3455   void VisitDeclRefExpr(DeclRefExpr *E) {
3456     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3457         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3458         E->isInstantiationDependent())
3459       return;
3460     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3461       // Check the datasharing rules for the expressions in the clauses.
3462       if (!CS) {
3463         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3464           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3465             Visit(CED->getInit());
3466             return;
3467           }
3468       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3469         // Do not analyze internal variables and do not enclose them into
3470         // implicit clauses.
3471         return;
3472       VD = VD->getCanonicalDecl();
3473       // Skip internally declared variables.
3474       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3475           !Stack->isImplicitTaskFirstprivate(VD))
3476         return;
3477       // Skip allocators in uses_allocators clauses.
3478       if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3479         return;
3480 
3481       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3482       // Check if the variable has explicit DSA set and stop analysis if it so.
3483       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3484         return;
3485 
3486       // Skip internally declared static variables.
3487       llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3488           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3489       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3490           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3491            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3492           !Stack->isImplicitTaskFirstprivate(VD))
3493         return;
3494 
3495       SourceLocation ELoc = E->getExprLoc();
3496       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3497       // The default(none) clause requires that each variable that is referenced
3498       // in the construct, and does not have a predetermined data-sharing
3499       // attribute, must have its data-sharing attribute explicitly determined
3500       // by being listed in a data-sharing attribute clause.
3501       if (DVar.CKind == OMPC_unknown &&
3502           (Stack->getDefaultDSA() == DSA_none ||
3503            Stack->getDefaultDSA() == DSA_firstprivate) &&
3504           isImplicitOrExplicitTaskingRegion(DKind) &&
3505           VarsWithInheritedDSA.count(VD) == 0) {
3506         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3507         if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3508           DSAStackTy::DSAVarData DVar =
3509               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3510           InheritedDSA = DVar.CKind == OMPC_unknown;
3511         }
3512         if (InheritedDSA)
3513           VarsWithInheritedDSA[VD] = E;
3514         return;
3515       }
3516 
3517       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3518       // If implicit-behavior is none, each variable referenced in the
3519       // construct that does not have a predetermined data-sharing attribute
3520       // and does not appear in a to or link clause on a declare target
3521       // directive must be listed in a data-mapping attribute clause, a
3522       // data-haring attribute clause (including a data-sharing attribute
3523       // clause on a combined construct where target. is one of the
3524       // constituent constructs), or an is_device_ptr clause.
3525       OpenMPDefaultmapClauseKind ClauseKind =
3526           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3527       if (SemaRef.getLangOpts().OpenMP >= 50) {
3528         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3529                               OMPC_DEFAULTMAP_MODIFIER_none;
3530         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3531             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3532           // Only check for data-mapping attribute and is_device_ptr here
3533           // since we have already make sure that the declaration does not
3534           // have a data-sharing attribute above
3535           if (!Stack->checkMappableExprComponentListsForDecl(
3536                   VD, /*CurrentRegionOnly=*/true,
3537                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3538                            MapExprComponents,
3539                        OpenMPClauseKind) {
3540                     auto MI = MapExprComponents.rbegin();
3541                     auto ME = MapExprComponents.rend();
3542                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3543                   })) {
3544             VarsWithInheritedDSA[VD] = E;
3545             return;
3546           }
3547         }
3548       }
3549       if (SemaRef.getLangOpts().OpenMP > 50) {
3550         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3551                                  OMPC_DEFAULTMAP_MODIFIER_present;
3552         if (IsModifierPresent) {
3553           if (llvm::find(ImplicitMapModifier[ClauseKind],
3554                          OMPC_MAP_MODIFIER_present) ==
3555               std::end(ImplicitMapModifier[ClauseKind])) {
3556             ImplicitMapModifier[ClauseKind].push_back(
3557                 OMPC_MAP_MODIFIER_present);
3558           }
3559         }
3560       }
3561 
3562       if (isOpenMPTargetExecutionDirective(DKind) &&
3563           !Stack->isLoopControlVariable(VD).first) {
3564         if (!Stack->checkMappableExprComponentListsForDecl(
3565                 VD, /*CurrentRegionOnly=*/true,
3566                 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3567                        StackComponents,
3568                    OpenMPClauseKind) {
3569                   // Variable is used if it has been marked as an array, array
3570                   // section, array shaping or the variable iself.
3571                   return StackComponents.size() == 1 ||
3572                          std::all_of(
3573                              std::next(StackComponents.rbegin()),
3574                              StackComponents.rend(),
3575                              [](const OMPClauseMappableExprCommon::
3576                                     MappableComponent &MC) {
3577                                return MC.getAssociatedDeclaration() ==
3578                                           nullptr &&
3579                                       (isa<OMPArraySectionExpr>(
3580                                            MC.getAssociatedExpression()) ||
3581                                        isa<OMPArrayShapingExpr>(
3582                                            MC.getAssociatedExpression()) ||
3583                                        isa<ArraySubscriptExpr>(
3584                                            MC.getAssociatedExpression()));
3585                              });
3586                 })) {
3587           bool IsFirstprivate = false;
3588           // By default lambdas are captured as firstprivates.
3589           if (const auto *RD =
3590                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3591             IsFirstprivate = RD->isLambda();
3592           IsFirstprivate =
3593               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3594           if (IsFirstprivate) {
3595             ImplicitFirstprivate.emplace_back(E);
3596           } else {
3597             OpenMPDefaultmapClauseModifier M =
3598                 Stack->getDefaultmapModifier(ClauseKind);
3599             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3600                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3601             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3602           }
3603           return;
3604         }
3605       }
3606 
3607       // OpenMP [2.9.3.6, Restrictions, p.2]
3608       //  A list item that appears in a reduction clause of the innermost
3609       //  enclosing worksharing or parallel construct may not be accessed in an
3610       //  explicit task.
3611       DVar = Stack->hasInnermostDSA(
3612           VD,
3613           [](OpenMPClauseKind C, bool AppliedToPointee) {
3614             return C == OMPC_reduction && !AppliedToPointee;
3615           },
3616           [](OpenMPDirectiveKind K) {
3617             return isOpenMPParallelDirective(K) ||
3618                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3619           },
3620           /*FromParent=*/true);
3621       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3622         ErrorFound = true;
3623         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3624         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3625         return;
3626       }
3627 
3628       // Define implicit data-sharing attributes for task.
3629       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3630       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3631            (Stack->getDefaultDSA() == DSA_firstprivate &&
3632             DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3633           !Stack->isLoopControlVariable(VD).first) {
3634         ImplicitFirstprivate.push_back(E);
3635         return;
3636       }
3637 
3638       // Store implicitly used globals with declare target link for parent
3639       // target.
3640       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3641           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3642         Stack->addToParentTargetRegionLinkGlobals(E);
3643         return;
3644       }
3645     }
3646   }
VisitMemberExpr(MemberExpr * E)3647   void VisitMemberExpr(MemberExpr *E) {
3648     if (E->isTypeDependent() || E->isValueDependent() ||
3649         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3650       return;
3651     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3652     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3653     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3654       if (!FD)
3655         return;
3656       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3657       // Check if the variable has explicit DSA set and stop analysis if it
3658       // so.
3659       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3660         return;
3661 
3662       if (isOpenMPTargetExecutionDirective(DKind) &&
3663           !Stack->isLoopControlVariable(FD).first &&
3664           !Stack->checkMappableExprComponentListsForDecl(
3665               FD, /*CurrentRegionOnly=*/true,
3666               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3667                      StackComponents,
3668                  OpenMPClauseKind) {
3669                 return isa<CXXThisExpr>(
3670                     cast<MemberExpr>(
3671                         StackComponents.back().getAssociatedExpression())
3672                         ->getBase()
3673                         ->IgnoreParens());
3674               })) {
3675         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3676         //  A bit-field cannot appear in a map clause.
3677         //
3678         if (FD->isBitField())
3679           return;
3680 
3681         // Check to see if the member expression is referencing a class that
3682         // has already been explicitly mapped
3683         if (Stack->isClassPreviouslyMapped(TE->getType()))
3684           return;
3685 
3686         OpenMPDefaultmapClauseModifier Modifier =
3687             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3688         OpenMPDefaultmapClauseKind ClauseKind =
3689             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3690         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3691             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3692         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3693         return;
3694       }
3695 
3696       SourceLocation ELoc = E->getExprLoc();
3697       // OpenMP [2.9.3.6, Restrictions, p.2]
3698       //  A list item that appears in a reduction clause of the innermost
3699       //  enclosing worksharing or parallel construct may not be accessed in
3700       //  an  explicit task.
3701       DVar = Stack->hasInnermostDSA(
3702           FD,
3703           [](OpenMPClauseKind C, bool AppliedToPointee) {
3704             return C == OMPC_reduction && !AppliedToPointee;
3705           },
3706           [](OpenMPDirectiveKind K) {
3707             return isOpenMPParallelDirective(K) ||
3708                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3709           },
3710           /*FromParent=*/true);
3711       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3712         ErrorFound = true;
3713         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3714         reportOriginalDsa(SemaRef, Stack, FD, DVar);
3715         return;
3716       }
3717 
3718       // Define implicit data-sharing attributes for task.
3719       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3720       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3721           !Stack->isLoopControlVariable(FD).first) {
3722         // Check if there is a captured expression for the current field in the
3723         // region. Do not mark it as firstprivate unless there is no captured
3724         // expression.
3725         // TODO: try to make it firstprivate.
3726         if (DVar.CKind != OMPC_unknown)
3727           ImplicitFirstprivate.push_back(E);
3728       }
3729       return;
3730     }
3731     if (isOpenMPTargetExecutionDirective(DKind)) {
3732       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3733       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3734                                         Stack->getCurrentDirective(),
3735                                         /*NoDiagnose=*/true))
3736         return;
3737       const auto *VD = cast<ValueDecl>(
3738           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3739       if (!Stack->checkMappableExprComponentListsForDecl(
3740               VD, /*CurrentRegionOnly=*/true,
3741               [&CurComponents](
3742                   OMPClauseMappableExprCommon::MappableExprComponentListRef
3743                       StackComponents,
3744                   OpenMPClauseKind) {
3745                 auto CCI = CurComponents.rbegin();
3746                 auto CCE = CurComponents.rend();
3747                 for (const auto &SC : llvm::reverse(StackComponents)) {
3748                   // Do both expressions have the same kind?
3749                   if (CCI->getAssociatedExpression()->getStmtClass() !=
3750                       SC.getAssociatedExpression()->getStmtClass())
3751                     if (!((isa<OMPArraySectionExpr>(
3752                                SC.getAssociatedExpression()) ||
3753                            isa<OMPArrayShapingExpr>(
3754                                SC.getAssociatedExpression())) &&
3755                           isa<ArraySubscriptExpr>(
3756                               CCI->getAssociatedExpression())))
3757                       return false;
3758 
3759                   const Decl *CCD = CCI->getAssociatedDeclaration();
3760                   const Decl *SCD = SC.getAssociatedDeclaration();
3761                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3762                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3763                   if (SCD != CCD)
3764                     return false;
3765                   std::advance(CCI, 1);
3766                   if (CCI == CCE)
3767                     break;
3768                 }
3769                 return true;
3770               })) {
3771         Visit(E->getBase());
3772       }
3773     } else if (!TryCaptureCXXThisMembers) {
3774       Visit(E->getBase());
3775     }
3776   }
VisitOMPExecutableDirective(OMPExecutableDirective * S)3777   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3778     for (OMPClause *C : S->clauses()) {
3779       // Skip analysis of arguments of implicitly defined firstprivate clause
3780       // for task|target directives.
3781       // Skip analysis of arguments of implicitly defined map clause for target
3782       // directives.
3783       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3784                  C->isImplicit() &&
3785                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3786         for (Stmt *CC : C->children()) {
3787           if (CC)
3788             Visit(CC);
3789         }
3790       }
3791     }
3792     // Check implicitly captured variables.
3793     VisitSubCaptures(S);
3794   }
VisitStmt(Stmt * S)3795   void VisitStmt(Stmt *S) {
3796     for (Stmt *C : S->children()) {
3797       if (C) {
3798         // Check implicitly captured variables in the task-based directives to
3799         // check if they must be firstprivatized.
3800         Visit(C);
3801       }
3802     }
3803   }
3804 
visitSubCaptures(CapturedStmt * S)3805   void visitSubCaptures(CapturedStmt *S) {
3806     for (const CapturedStmt::Capture &Cap : S->captures()) {
3807       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3808         continue;
3809       VarDecl *VD = Cap.getCapturedVar();
3810       // Do not try to map the variable if it or its sub-component was mapped
3811       // already.
3812       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3813           Stack->checkMappableExprComponentListsForDecl(
3814               VD, /*CurrentRegionOnly=*/true,
3815               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3816                  OpenMPClauseKind) { return true; }))
3817         continue;
3818       DeclRefExpr *DRE = buildDeclRefExpr(
3819           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3820           Cap.getLocation(), /*RefersToCapture=*/true);
3821       Visit(DRE);
3822     }
3823   }
isErrorFound() const3824   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3825   ArrayRef<Expr *> getImplicitFirstprivate() const {
3826     return ImplicitFirstprivate;
3827   }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const3828   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3829                                   OpenMPMapClauseKind MK) const {
3830     return ImplicitMap[DK][MK];
3831   }
3832   ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const3833   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3834     return ImplicitMapModifier[Kind];
3835   }
getVarsWithInheritedDSA() const3836   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3837     return VarsWithInheritedDSA;
3838   }
3839 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3840   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3841       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3842     // Process declare target link variables for the target directives.
3843     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3844       for (DeclRefExpr *E : Stack->getLinkGlobals())
3845         Visit(E);
3846     }
3847   }
3848 };
3849 } // namespace
3850 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3851 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3852   switch (DKind) {
3853   case OMPD_parallel:
3854   case OMPD_parallel_for:
3855   case OMPD_parallel_for_simd:
3856   case OMPD_parallel_sections:
3857   case OMPD_parallel_master:
3858   case OMPD_teams:
3859   case OMPD_teams_distribute:
3860   case OMPD_teams_distribute_simd: {
3861     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3862     QualType KmpInt32PtrTy =
3863         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3864     Sema::CapturedParamNameType Params[] = {
3865         std::make_pair(".global_tid.", KmpInt32PtrTy),
3866         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3867         std::make_pair(StringRef(), QualType()) // __context with shared vars
3868     };
3869     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3870                              Params);
3871     break;
3872   }
3873   case OMPD_target_teams:
3874   case OMPD_target_parallel:
3875   case OMPD_target_parallel_for:
3876   case OMPD_target_parallel_for_simd:
3877   case OMPD_target_teams_distribute:
3878   case OMPD_target_teams_distribute_simd: {
3879     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3880     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3881     QualType KmpInt32PtrTy =
3882         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3883     QualType Args[] = {VoidPtrTy};
3884     FunctionProtoType::ExtProtoInfo EPI;
3885     EPI.Variadic = true;
3886     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3887     Sema::CapturedParamNameType Params[] = {
3888         std::make_pair(".global_tid.", KmpInt32Ty),
3889         std::make_pair(".part_id.", KmpInt32PtrTy),
3890         std::make_pair(".privates.", VoidPtrTy),
3891         std::make_pair(
3892             ".copy_fn.",
3893             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3894         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3895         std::make_pair(StringRef(), QualType()) // __context with shared vars
3896     };
3897     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3898                              Params, /*OpenMPCaptureLevel=*/0);
3899     // Mark this captured region as inlined, because we don't use outlined
3900     // function directly.
3901     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3902         AlwaysInlineAttr::CreateImplicit(
3903             Context, {}, AttributeCommonInfo::AS_Keyword,
3904             AlwaysInlineAttr::Keyword_forceinline));
3905     Sema::CapturedParamNameType ParamsTarget[] = {
3906         std::make_pair(StringRef(), QualType()) // __context with shared vars
3907     };
3908     // Start a captured region for 'target' with no implicit parameters.
3909     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3910                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
3911     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3912         std::make_pair(".global_tid.", KmpInt32PtrTy),
3913         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3914         std::make_pair(StringRef(), QualType()) // __context with shared vars
3915     };
3916     // Start a captured region for 'teams' or 'parallel'.  Both regions have
3917     // the same implicit parameters.
3918     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3919                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3920     break;
3921   }
3922   case OMPD_target:
3923   case OMPD_target_simd: {
3924     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3925     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3926     QualType KmpInt32PtrTy =
3927         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3928     QualType Args[] = {VoidPtrTy};
3929     FunctionProtoType::ExtProtoInfo EPI;
3930     EPI.Variadic = true;
3931     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3932     Sema::CapturedParamNameType Params[] = {
3933         std::make_pair(".global_tid.", KmpInt32Ty),
3934         std::make_pair(".part_id.", KmpInt32PtrTy),
3935         std::make_pair(".privates.", VoidPtrTy),
3936         std::make_pair(
3937             ".copy_fn.",
3938             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3939         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3940         std::make_pair(StringRef(), QualType()) // __context with shared vars
3941     };
3942     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3943                              Params, /*OpenMPCaptureLevel=*/0);
3944     // Mark this captured region as inlined, because we don't use outlined
3945     // function directly.
3946     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3947         AlwaysInlineAttr::CreateImplicit(
3948             Context, {}, AttributeCommonInfo::AS_Keyword,
3949             AlwaysInlineAttr::Keyword_forceinline));
3950     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3951                              std::make_pair(StringRef(), QualType()),
3952                              /*OpenMPCaptureLevel=*/1);
3953     break;
3954   }
3955   case OMPD_atomic:
3956   case OMPD_critical:
3957   case OMPD_section:
3958   case OMPD_master:
3959     break;
3960   case OMPD_simd:
3961   case OMPD_for:
3962   case OMPD_for_simd:
3963   case OMPD_sections:
3964   case OMPD_single:
3965   case OMPD_taskgroup:
3966   case OMPD_distribute:
3967   case OMPD_distribute_simd:
3968   case OMPD_ordered:
3969   case OMPD_target_data: {
3970     Sema::CapturedParamNameType Params[] = {
3971         std::make_pair(StringRef(), QualType()) // __context with shared vars
3972     };
3973     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3974                              Params);
3975     break;
3976   }
3977   case OMPD_task: {
3978     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3979     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3980     QualType KmpInt32PtrTy =
3981         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3982     QualType Args[] = {VoidPtrTy};
3983     FunctionProtoType::ExtProtoInfo EPI;
3984     EPI.Variadic = true;
3985     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3986     Sema::CapturedParamNameType Params[] = {
3987         std::make_pair(".global_tid.", KmpInt32Ty),
3988         std::make_pair(".part_id.", KmpInt32PtrTy),
3989         std::make_pair(".privates.", VoidPtrTy),
3990         std::make_pair(
3991             ".copy_fn.",
3992             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3993         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3994         std::make_pair(StringRef(), QualType()) // __context with shared vars
3995     };
3996     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3997                              Params);
3998     // Mark this captured region as inlined, because we don't use outlined
3999     // function directly.
4000     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4001         AlwaysInlineAttr::CreateImplicit(
4002             Context, {}, AttributeCommonInfo::AS_Keyword,
4003             AlwaysInlineAttr::Keyword_forceinline));
4004     break;
4005   }
4006   case OMPD_taskloop:
4007   case OMPD_taskloop_simd:
4008   case OMPD_master_taskloop:
4009   case OMPD_master_taskloop_simd: {
4010     QualType KmpInt32Ty =
4011         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4012             .withConst();
4013     QualType KmpUInt64Ty =
4014         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4015             .withConst();
4016     QualType KmpInt64Ty =
4017         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4018             .withConst();
4019     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4020     QualType KmpInt32PtrTy =
4021         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4022     QualType Args[] = {VoidPtrTy};
4023     FunctionProtoType::ExtProtoInfo EPI;
4024     EPI.Variadic = true;
4025     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4026     Sema::CapturedParamNameType Params[] = {
4027         std::make_pair(".global_tid.", KmpInt32Ty),
4028         std::make_pair(".part_id.", KmpInt32PtrTy),
4029         std::make_pair(".privates.", VoidPtrTy),
4030         std::make_pair(
4031             ".copy_fn.",
4032             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4033         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4034         std::make_pair(".lb.", KmpUInt64Ty),
4035         std::make_pair(".ub.", KmpUInt64Ty),
4036         std::make_pair(".st.", KmpInt64Ty),
4037         std::make_pair(".liter.", KmpInt32Ty),
4038         std::make_pair(".reductions.", VoidPtrTy),
4039         std::make_pair(StringRef(), QualType()) // __context with shared vars
4040     };
4041     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4042                              Params);
4043     // Mark this captured region as inlined, because we don't use outlined
4044     // function directly.
4045     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4046         AlwaysInlineAttr::CreateImplicit(
4047             Context, {}, AttributeCommonInfo::AS_Keyword,
4048             AlwaysInlineAttr::Keyword_forceinline));
4049     break;
4050   }
4051   case OMPD_parallel_master_taskloop:
4052   case OMPD_parallel_master_taskloop_simd: {
4053     QualType KmpInt32Ty =
4054         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4055             .withConst();
4056     QualType KmpUInt64Ty =
4057         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4058             .withConst();
4059     QualType KmpInt64Ty =
4060         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4061             .withConst();
4062     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4063     QualType KmpInt32PtrTy =
4064         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4065     Sema::CapturedParamNameType ParamsParallel[] = {
4066         std::make_pair(".global_tid.", KmpInt32PtrTy),
4067         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4068         std::make_pair(StringRef(), QualType()) // __context with shared vars
4069     };
4070     // Start a captured region for 'parallel'.
4071     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4072                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4073     QualType Args[] = {VoidPtrTy};
4074     FunctionProtoType::ExtProtoInfo EPI;
4075     EPI.Variadic = true;
4076     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4077     Sema::CapturedParamNameType Params[] = {
4078         std::make_pair(".global_tid.", KmpInt32Ty),
4079         std::make_pair(".part_id.", KmpInt32PtrTy),
4080         std::make_pair(".privates.", VoidPtrTy),
4081         std::make_pair(
4082             ".copy_fn.",
4083             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4084         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4085         std::make_pair(".lb.", KmpUInt64Ty),
4086         std::make_pair(".ub.", KmpUInt64Ty),
4087         std::make_pair(".st.", KmpInt64Ty),
4088         std::make_pair(".liter.", KmpInt32Ty),
4089         std::make_pair(".reductions.", VoidPtrTy),
4090         std::make_pair(StringRef(), QualType()) // __context with shared vars
4091     };
4092     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4093                              Params, /*OpenMPCaptureLevel=*/1);
4094     // Mark this captured region as inlined, because we don't use outlined
4095     // function directly.
4096     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4097         AlwaysInlineAttr::CreateImplicit(
4098             Context, {}, AttributeCommonInfo::AS_Keyword,
4099             AlwaysInlineAttr::Keyword_forceinline));
4100     break;
4101   }
4102   case OMPD_distribute_parallel_for_simd:
4103   case OMPD_distribute_parallel_for: {
4104     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4105     QualType KmpInt32PtrTy =
4106         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4107     Sema::CapturedParamNameType Params[] = {
4108         std::make_pair(".global_tid.", KmpInt32PtrTy),
4109         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4110         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4111         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4112         std::make_pair(StringRef(), QualType()) // __context with shared vars
4113     };
4114     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4115                              Params);
4116     break;
4117   }
4118   case OMPD_target_teams_distribute_parallel_for:
4119   case OMPD_target_teams_distribute_parallel_for_simd: {
4120     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4121     QualType KmpInt32PtrTy =
4122         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4123     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4124 
4125     QualType Args[] = {VoidPtrTy};
4126     FunctionProtoType::ExtProtoInfo EPI;
4127     EPI.Variadic = true;
4128     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4129     Sema::CapturedParamNameType Params[] = {
4130         std::make_pair(".global_tid.", KmpInt32Ty),
4131         std::make_pair(".part_id.", KmpInt32PtrTy),
4132         std::make_pair(".privates.", VoidPtrTy),
4133         std::make_pair(
4134             ".copy_fn.",
4135             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4136         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4137         std::make_pair(StringRef(), QualType()) // __context with shared vars
4138     };
4139     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4140                              Params, /*OpenMPCaptureLevel=*/0);
4141     // Mark this captured region as inlined, because we don't use outlined
4142     // function directly.
4143     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4144         AlwaysInlineAttr::CreateImplicit(
4145             Context, {}, AttributeCommonInfo::AS_Keyword,
4146             AlwaysInlineAttr::Keyword_forceinline));
4147     Sema::CapturedParamNameType ParamsTarget[] = {
4148         std::make_pair(StringRef(), QualType()) // __context with shared vars
4149     };
4150     // Start a captured region for 'target' with no implicit parameters.
4151     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4152                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4153 
4154     Sema::CapturedParamNameType ParamsTeams[] = {
4155         std::make_pair(".global_tid.", KmpInt32PtrTy),
4156         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4157         std::make_pair(StringRef(), QualType()) // __context with shared vars
4158     };
4159     // Start a captured region for 'target' with no implicit parameters.
4160     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4161                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4162 
4163     Sema::CapturedParamNameType ParamsParallel[] = {
4164         std::make_pair(".global_tid.", KmpInt32PtrTy),
4165         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4166         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4167         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4168         std::make_pair(StringRef(), QualType()) // __context with shared vars
4169     };
4170     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4171     // the same implicit parameters.
4172     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4173                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4174     break;
4175   }
4176 
4177   case OMPD_teams_distribute_parallel_for:
4178   case OMPD_teams_distribute_parallel_for_simd: {
4179     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4180     QualType KmpInt32PtrTy =
4181         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4182 
4183     Sema::CapturedParamNameType ParamsTeams[] = {
4184         std::make_pair(".global_tid.", KmpInt32PtrTy),
4185         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4186         std::make_pair(StringRef(), QualType()) // __context with shared vars
4187     };
4188     // Start a captured region for 'target' with no implicit parameters.
4189     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4190                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4191 
4192     Sema::CapturedParamNameType ParamsParallel[] = {
4193         std::make_pair(".global_tid.", KmpInt32PtrTy),
4194         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4195         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4196         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4197         std::make_pair(StringRef(), QualType()) // __context with shared vars
4198     };
4199     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4200     // the same implicit parameters.
4201     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4202                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4203     break;
4204   }
4205   case OMPD_target_update:
4206   case OMPD_target_enter_data:
4207   case OMPD_target_exit_data: {
4208     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4210     QualType KmpInt32PtrTy =
4211         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4212     QualType Args[] = {VoidPtrTy};
4213     FunctionProtoType::ExtProtoInfo EPI;
4214     EPI.Variadic = true;
4215     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4216     Sema::CapturedParamNameType Params[] = {
4217         std::make_pair(".global_tid.", KmpInt32Ty),
4218         std::make_pair(".part_id.", KmpInt32PtrTy),
4219         std::make_pair(".privates.", VoidPtrTy),
4220         std::make_pair(
4221             ".copy_fn.",
4222             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4223         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4224         std::make_pair(StringRef(), QualType()) // __context with shared vars
4225     };
4226     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4227                              Params);
4228     // Mark this captured region as inlined, because we don't use outlined
4229     // function directly.
4230     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4231         AlwaysInlineAttr::CreateImplicit(
4232             Context, {}, AttributeCommonInfo::AS_Keyword,
4233             AlwaysInlineAttr::Keyword_forceinline));
4234     break;
4235   }
4236   case OMPD_threadprivate:
4237   case OMPD_allocate:
4238   case OMPD_taskyield:
4239   case OMPD_barrier:
4240   case OMPD_taskwait:
4241   case OMPD_cancellation_point:
4242   case OMPD_cancel:
4243   case OMPD_flush:
4244   case OMPD_depobj:
4245   case OMPD_scan:
4246   case OMPD_declare_reduction:
4247   case OMPD_declare_mapper:
4248   case OMPD_declare_simd:
4249   case OMPD_declare_target:
4250   case OMPD_end_declare_target:
4251   case OMPD_requires:
4252   case OMPD_declare_variant:
4253   case OMPD_begin_declare_variant:
4254   case OMPD_end_declare_variant:
4255     llvm_unreachable("OpenMP Directive is not allowed");
4256   case OMPD_unknown:
4257   default:
4258     llvm_unreachable("Unknown OpenMP directive");
4259   }
4260   DSAStack->setContext(CurContext);
4261 }
4262 
getNumberOfConstructScopes(unsigned Level) const4263 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4264   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4265 }
4266 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4267 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4268   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4269   getOpenMPCaptureRegions(CaptureRegions, DKind);
4270   return CaptureRegions.size();
4271 }
4272 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4273 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4274                                              Expr *CaptureExpr, bool WithInit,
4275                                              bool AsExpression) {
4276   assert(CaptureExpr);
4277   ASTContext &C = S.getASTContext();
4278   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4279   QualType Ty = Init->getType();
4280   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4281     if (S.getLangOpts().CPlusPlus) {
4282       Ty = C.getLValueReferenceType(Ty);
4283     } else {
4284       Ty = C.getPointerType(Ty);
4285       ExprResult Res =
4286           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4287       if (!Res.isUsable())
4288         return nullptr;
4289       Init = Res.get();
4290     }
4291     WithInit = true;
4292   }
4293   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4294                                           CaptureExpr->getBeginLoc());
4295   if (!WithInit)
4296     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4297   S.CurContext->addHiddenDecl(CED);
4298   Sema::TentativeAnalysisScope Trap(S);
4299   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4300   return CED;
4301 }
4302 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4303 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4304                                  bool WithInit) {
4305   OMPCapturedExprDecl *CD;
4306   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4307     CD = cast<OMPCapturedExprDecl>(VD);
4308   else
4309     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4310                           /*AsExpression=*/false);
4311   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4312                           CaptureExpr->getExprLoc());
4313 }
4314 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4315 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4316   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4317   if (!Ref) {
4318     OMPCapturedExprDecl *CD = buildCaptureDecl(
4319         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4320         /*WithInit=*/true, /*AsExpression=*/true);
4321     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4322                            CaptureExpr->getExprLoc());
4323   }
4324   ExprResult Res = Ref;
4325   if (!S.getLangOpts().CPlusPlus &&
4326       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4327       Ref->getType()->isPointerType()) {
4328     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4329     if (!Res.isUsable())
4330       return ExprError();
4331   }
4332   return S.DefaultLvalueConversion(Res.get());
4333 }
4334 
4335 namespace {
4336 // OpenMP directives parsed in this section are represented as a
4337 // CapturedStatement with an associated statement.  If a syntax error
4338 // is detected during the parsing of the associated statement, the
4339 // compiler must abort processing and close the CapturedStatement.
4340 //
4341 // Combined directives such as 'target parallel' have more than one
4342 // nested CapturedStatements.  This RAII ensures that we unwind out
4343 // of all the nested CapturedStatements when an error is found.
4344 class CaptureRegionUnwinderRAII {
4345 private:
4346   Sema &S;
4347   bool &ErrorFound;
4348   OpenMPDirectiveKind DKind = OMPD_unknown;
4349 
4350 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4351   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4352                             OpenMPDirectiveKind DKind)
4353       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4354   ~CaptureRegionUnwinderRAII() {
4355     if (ErrorFound) {
4356       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4357       while (--ThisCaptureLevel >= 0)
4358         S.ActOnCapturedRegionError();
4359     }
4360   }
4361 };
4362 } // namespace
4363 
tryCaptureOpenMPLambdas(ValueDecl * V)4364 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4365   // Capture variables captured by reference in lambdas for target-based
4366   // directives.
4367   if (!CurContext->isDependentContext() &&
4368       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4369        isOpenMPTargetDataManagementDirective(
4370            DSAStack->getCurrentDirective()))) {
4371     QualType Type = V->getType();
4372     if (const auto *RD = Type.getCanonicalType()
4373                              .getNonReferenceType()
4374                              ->getAsCXXRecordDecl()) {
4375       bool SavedForceCaptureByReferenceInTargetExecutable =
4376           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4377       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4378           /*V=*/true);
4379       if (RD->isLambda()) {
4380         llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4381         FieldDecl *ThisCapture;
4382         RD->getCaptureFields(Captures, ThisCapture);
4383         for (const LambdaCapture &LC : RD->captures()) {
4384           if (LC.getCaptureKind() == LCK_ByRef) {
4385             VarDecl *VD = LC.getCapturedVar();
4386             DeclContext *VDC = VD->getDeclContext();
4387             if (!VDC->Encloses(CurContext))
4388               continue;
4389             MarkVariableReferenced(LC.getLocation(), VD);
4390           } else if (LC.getCaptureKind() == LCK_This) {
4391             QualType ThisTy = getCurrentThisType();
4392             if (!ThisTy.isNull() &&
4393                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4394               CheckCXXThisCapture(LC.getLocation());
4395           }
4396         }
4397       }
4398       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4399           SavedForceCaptureByReferenceInTargetExecutable);
4400     }
4401   }
4402 }
4403 
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4404 static bool checkOrderedOrderSpecified(Sema &S,
4405                                        const ArrayRef<OMPClause *> Clauses) {
4406   const OMPOrderedClause *Ordered = nullptr;
4407   const OMPOrderClause *Order = nullptr;
4408 
4409   for (const OMPClause *Clause : Clauses) {
4410     if (Clause->getClauseKind() == OMPC_ordered)
4411       Ordered = cast<OMPOrderedClause>(Clause);
4412     else if (Clause->getClauseKind() == OMPC_order) {
4413       Order = cast<OMPOrderClause>(Clause);
4414       if (Order->getKind() != OMPC_ORDER_concurrent)
4415         Order = nullptr;
4416     }
4417     if (Ordered && Order)
4418       break;
4419   }
4420 
4421   if (Ordered && Order) {
4422     S.Diag(Order->getKindKwLoc(),
4423            diag::err_omp_simple_clause_incompatible_with_ordered)
4424         << getOpenMPClauseName(OMPC_order)
4425         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4426         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4427     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4428         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4429     return true;
4430   }
4431   return false;
4432 }
4433 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4434 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4435                                       ArrayRef<OMPClause *> Clauses) {
4436   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4437       DSAStack->getCurrentDirective() == OMPD_critical ||
4438       DSAStack->getCurrentDirective() == OMPD_section ||
4439       DSAStack->getCurrentDirective() == OMPD_master)
4440     return S;
4441 
4442   bool ErrorFound = false;
4443   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4444       *this, ErrorFound, DSAStack->getCurrentDirective());
4445   if (!S.isUsable()) {
4446     ErrorFound = true;
4447     return StmtError();
4448   }
4449 
4450   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4451   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4452   OMPOrderedClause *OC = nullptr;
4453   OMPScheduleClause *SC = nullptr;
4454   SmallVector<const OMPLinearClause *, 4> LCs;
4455   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4456   // This is required for proper codegen.
4457   for (OMPClause *Clause : Clauses) {
4458     if (!LangOpts.OpenMPSimd &&
4459         isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4460         Clause->getClauseKind() == OMPC_in_reduction) {
4461       // Capture taskgroup task_reduction descriptors inside the tasking regions
4462       // with the corresponding in_reduction items.
4463       auto *IRC = cast<OMPInReductionClause>(Clause);
4464       for (Expr *E : IRC->taskgroup_descriptors())
4465         if (E)
4466           MarkDeclarationsReferencedInExpr(E);
4467     }
4468     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4469         Clause->getClauseKind() == OMPC_copyprivate ||
4470         (getLangOpts().OpenMPUseTLS &&
4471          getASTContext().getTargetInfo().isTLSSupported() &&
4472          Clause->getClauseKind() == OMPC_copyin)) {
4473       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4474       // Mark all variables in private list clauses as used in inner region.
4475       for (Stmt *VarRef : Clause->children()) {
4476         if (auto *E = cast_or_null<Expr>(VarRef)) {
4477           MarkDeclarationsReferencedInExpr(E);
4478         }
4479       }
4480       DSAStack->setForceVarCapturing(/*V=*/false);
4481     } else if (CaptureRegions.size() > 1 ||
4482                CaptureRegions.back() != OMPD_unknown) {
4483       if (auto *C = OMPClauseWithPreInit::get(Clause))
4484         PICs.push_back(C);
4485       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4486         if (Expr *E = C->getPostUpdateExpr())
4487           MarkDeclarationsReferencedInExpr(E);
4488       }
4489     }
4490     if (Clause->getClauseKind() == OMPC_schedule)
4491       SC = cast<OMPScheduleClause>(Clause);
4492     else if (Clause->getClauseKind() == OMPC_ordered)
4493       OC = cast<OMPOrderedClause>(Clause);
4494     else if (Clause->getClauseKind() == OMPC_linear)
4495       LCs.push_back(cast<OMPLinearClause>(Clause));
4496   }
4497   // Capture allocator expressions if used.
4498   for (Expr *E : DSAStack->getInnerAllocators())
4499     MarkDeclarationsReferencedInExpr(E);
4500   // OpenMP, 2.7.1 Loop Construct, Restrictions
4501   // The nonmonotonic modifier cannot be specified if an ordered clause is
4502   // specified.
4503   if (SC &&
4504       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4505        SC->getSecondScheduleModifier() ==
4506            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4507       OC) {
4508     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4509              ? SC->getFirstScheduleModifierLoc()
4510              : SC->getSecondScheduleModifierLoc(),
4511          diag::err_omp_simple_clause_incompatible_with_ordered)
4512         << getOpenMPClauseName(OMPC_schedule)
4513         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4514                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4515         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4516     ErrorFound = true;
4517   }
4518   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4519   // If an order(concurrent) clause is present, an ordered clause may not appear
4520   // on the same directive.
4521   if (checkOrderedOrderSpecified(*this, Clauses))
4522     ErrorFound = true;
4523   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4524     for (const OMPLinearClause *C : LCs) {
4525       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4526           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4527     }
4528     ErrorFound = true;
4529   }
4530   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4531       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4532       OC->getNumForLoops()) {
4533     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4534         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4535     ErrorFound = true;
4536   }
4537   if (ErrorFound) {
4538     return StmtError();
4539   }
4540   StmtResult SR = S;
4541   unsigned CompletedRegions = 0;
4542   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4543     // Mark all variables in private list clauses as used in inner region.
4544     // Required for proper codegen of combined directives.
4545     // TODO: add processing for other clauses.
4546     if (ThisCaptureRegion != OMPD_unknown) {
4547       for (const clang::OMPClauseWithPreInit *C : PICs) {
4548         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4549         // Find the particular capture region for the clause if the
4550         // directive is a combined one with multiple capture regions.
4551         // If the directive is not a combined one, the capture region
4552         // associated with the clause is OMPD_unknown and is generated
4553         // only once.
4554         if (CaptureRegion == ThisCaptureRegion ||
4555             CaptureRegion == OMPD_unknown) {
4556           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4557             for (Decl *D : DS->decls())
4558               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4559           }
4560         }
4561       }
4562     }
4563     if (ThisCaptureRegion == OMPD_target) {
4564       // Capture allocator traits in the target region. They are used implicitly
4565       // and, thus, are not captured by default.
4566       for (OMPClause *C : Clauses) {
4567         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4568           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4569                ++I) {
4570             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4571             if (Expr *E = D.AllocatorTraits)
4572               MarkDeclarationsReferencedInExpr(E);
4573           }
4574           continue;
4575         }
4576       }
4577     }
4578     if (++CompletedRegions == CaptureRegions.size())
4579       DSAStack->setBodyComplete();
4580     SR = ActOnCapturedRegionEnd(SR.get());
4581   }
4582   return SR;
4583 }
4584 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4585 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4586                               OpenMPDirectiveKind CancelRegion,
4587                               SourceLocation StartLoc) {
4588   // CancelRegion is only needed for cancel and cancellation_point.
4589   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4590     return false;
4591 
4592   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4593       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4594     return false;
4595 
4596   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4597       << getOpenMPDirectiveName(CancelRegion);
4598   return true;
4599 }
4600 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4601 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4602                                   OpenMPDirectiveKind CurrentRegion,
4603                                   const DeclarationNameInfo &CurrentName,
4604                                   OpenMPDirectiveKind CancelRegion,
4605                                   SourceLocation StartLoc) {
4606   if (Stack->getCurScope()) {
4607     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4608     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4609     bool NestingProhibited = false;
4610     bool CloseNesting = true;
4611     bool OrphanSeen = false;
4612     enum {
4613       NoRecommend,
4614       ShouldBeInParallelRegion,
4615       ShouldBeInOrderedRegion,
4616       ShouldBeInTargetRegion,
4617       ShouldBeInTeamsRegion,
4618       ShouldBeInLoopSimdRegion,
4619     } Recommend = NoRecommend;
4620     if (isOpenMPSimdDirective(ParentRegion) &&
4621         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4622          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4623           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4624           CurrentRegion != OMPD_scan))) {
4625       // OpenMP [2.16, Nesting of Regions]
4626       // OpenMP constructs may not be nested inside a simd region.
4627       // OpenMP [2.8.1,simd Construct, Restrictions]
4628       // An ordered construct with the simd clause is the only OpenMP
4629       // construct that can appear in the simd region.
4630       // Allowing a SIMD construct nested in another SIMD construct is an
4631       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4632       // message.
4633       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4634       // The only OpenMP constructs that can be encountered during execution of
4635       // a simd region are the atomic construct, the loop construct, the simd
4636       // construct and the ordered construct with the simd clause.
4637       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4638                                  ? diag::err_omp_prohibited_region_simd
4639                                  : diag::warn_omp_nesting_simd)
4640           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4641       return CurrentRegion != OMPD_simd;
4642     }
4643     if (ParentRegion == OMPD_atomic) {
4644       // OpenMP [2.16, Nesting of Regions]
4645       // OpenMP constructs may not be nested inside an atomic region.
4646       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4647       return true;
4648     }
4649     if (CurrentRegion == OMPD_section) {
4650       // OpenMP [2.7.2, sections Construct, Restrictions]
4651       // Orphaned section directives are prohibited. That is, the section
4652       // directives must appear within the sections construct and must not be
4653       // encountered elsewhere in the sections region.
4654       if (ParentRegion != OMPD_sections &&
4655           ParentRegion != OMPD_parallel_sections) {
4656         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4657             << (ParentRegion != OMPD_unknown)
4658             << getOpenMPDirectiveName(ParentRegion);
4659         return true;
4660       }
4661       return false;
4662     }
4663     // Allow some constructs (except teams and cancellation constructs) to be
4664     // orphaned (they could be used in functions, called from OpenMP regions
4665     // with the required preconditions).
4666     if (ParentRegion == OMPD_unknown &&
4667         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4668         CurrentRegion != OMPD_cancellation_point &&
4669         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4670       return false;
4671     if (CurrentRegion == OMPD_cancellation_point ||
4672         CurrentRegion == OMPD_cancel) {
4673       // OpenMP [2.16, Nesting of Regions]
4674       // A cancellation point construct for which construct-type-clause is
4675       // taskgroup must be nested inside a task construct. A cancellation
4676       // point construct for which construct-type-clause is not taskgroup must
4677       // be closely nested inside an OpenMP construct that matches the type
4678       // specified in construct-type-clause.
4679       // A cancel construct for which construct-type-clause is taskgroup must be
4680       // nested inside a task construct. A cancel construct for which
4681       // construct-type-clause is not taskgroup must be closely nested inside an
4682       // OpenMP construct that matches the type specified in
4683       // construct-type-clause.
4684       NestingProhibited =
4685           !((CancelRegion == OMPD_parallel &&
4686              (ParentRegion == OMPD_parallel ||
4687               ParentRegion == OMPD_target_parallel)) ||
4688             (CancelRegion == OMPD_for &&
4689              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4690               ParentRegion == OMPD_target_parallel_for ||
4691               ParentRegion == OMPD_distribute_parallel_for ||
4692               ParentRegion == OMPD_teams_distribute_parallel_for ||
4693               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4694             (CancelRegion == OMPD_taskgroup &&
4695              (ParentRegion == OMPD_task ||
4696               (SemaRef.getLangOpts().OpenMP >= 50 &&
4697                (ParentRegion == OMPD_taskloop ||
4698                 ParentRegion == OMPD_master_taskloop ||
4699                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4700             (CancelRegion == OMPD_sections &&
4701              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4702               ParentRegion == OMPD_parallel_sections)));
4703       OrphanSeen = ParentRegion == OMPD_unknown;
4704     } else if (CurrentRegion == OMPD_master) {
4705       // OpenMP [2.16, Nesting of Regions]
4706       // A master region may not be closely nested inside a worksharing,
4707       // atomic, or explicit task region.
4708       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4709                           isOpenMPTaskingDirective(ParentRegion);
4710     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4711       // OpenMP [2.16, Nesting of Regions]
4712       // A critical region may not be nested (closely or otherwise) inside a
4713       // critical region with the same name. Note that this restriction is not
4714       // sufficient to prevent deadlock.
4715       SourceLocation PreviousCriticalLoc;
4716       bool DeadLock = Stack->hasDirective(
4717           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4718                                               const DeclarationNameInfo &DNI,
4719                                               SourceLocation Loc) {
4720             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4721               PreviousCriticalLoc = Loc;
4722               return true;
4723             }
4724             return false;
4725           },
4726           false /* skip top directive */);
4727       if (DeadLock) {
4728         SemaRef.Diag(StartLoc,
4729                      diag::err_omp_prohibited_region_critical_same_name)
4730             << CurrentName.getName();
4731         if (PreviousCriticalLoc.isValid())
4732           SemaRef.Diag(PreviousCriticalLoc,
4733                        diag::note_omp_previous_critical_region);
4734         return true;
4735       }
4736     } else if (CurrentRegion == OMPD_barrier) {
4737       // OpenMP [2.16, Nesting of Regions]
4738       // A barrier region may not be closely nested inside a worksharing,
4739       // explicit task, critical, ordered, atomic, or master region.
4740       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4741                           isOpenMPTaskingDirective(ParentRegion) ||
4742                           ParentRegion == OMPD_master ||
4743                           ParentRegion == OMPD_parallel_master ||
4744                           ParentRegion == OMPD_critical ||
4745                           ParentRegion == OMPD_ordered;
4746     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4747                !isOpenMPParallelDirective(CurrentRegion) &&
4748                !isOpenMPTeamsDirective(CurrentRegion)) {
4749       // OpenMP [2.16, Nesting of Regions]
4750       // A worksharing region may not be closely nested inside a worksharing,
4751       // explicit task, critical, ordered, atomic, or master region.
4752       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4753                           isOpenMPTaskingDirective(ParentRegion) ||
4754                           ParentRegion == OMPD_master ||
4755                           ParentRegion == OMPD_parallel_master ||
4756                           ParentRegion == OMPD_critical ||
4757                           ParentRegion == OMPD_ordered;
4758       Recommend = ShouldBeInParallelRegion;
4759     } else if (CurrentRegion == OMPD_ordered) {
4760       // OpenMP [2.16, Nesting of Regions]
4761       // An ordered region may not be closely nested inside a critical,
4762       // atomic, or explicit task region.
4763       // An ordered region must be closely nested inside a loop region (or
4764       // parallel loop region) with an ordered clause.
4765       // OpenMP [2.8.1,simd Construct, Restrictions]
4766       // An ordered construct with the simd clause is the only OpenMP construct
4767       // that can appear in the simd region.
4768       NestingProhibited = ParentRegion == OMPD_critical ||
4769                           isOpenMPTaskingDirective(ParentRegion) ||
4770                           !(isOpenMPSimdDirective(ParentRegion) ||
4771                             Stack->isParentOrderedRegion());
4772       Recommend = ShouldBeInOrderedRegion;
4773     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4774       // OpenMP [2.16, Nesting of Regions]
4775       // If specified, a teams construct must be contained within a target
4776       // construct.
4777       NestingProhibited =
4778           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4779           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4780            ParentRegion != OMPD_target);
4781       OrphanSeen = ParentRegion == OMPD_unknown;
4782       Recommend = ShouldBeInTargetRegion;
4783     } else if (CurrentRegion == OMPD_scan) {
4784       // OpenMP [2.16, Nesting of Regions]
4785       // If specified, a teams construct must be contained within a target
4786       // construct.
4787       NestingProhibited =
4788           SemaRef.LangOpts.OpenMP < 50 ||
4789           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4790            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4791            ParentRegion != OMPD_parallel_for_simd);
4792       OrphanSeen = ParentRegion == OMPD_unknown;
4793       Recommend = ShouldBeInLoopSimdRegion;
4794     }
4795     if (!NestingProhibited &&
4796         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4797         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4798         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4799       // OpenMP [2.16, Nesting of Regions]
4800       // distribute, parallel, parallel sections, parallel workshare, and the
4801       // parallel loop and parallel loop SIMD constructs are the only OpenMP
4802       // constructs that can be closely nested in the teams region.
4803       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4804                           !isOpenMPDistributeDirective(CurrentRegion);
4805       Recommend = ShouldBeInParallelRegion;
4806     }
4807     if (!NestingProhibited &&
4808         isOpenMPNestingDistributeDirective(CurrentRegion)) {
4809       // OpenMP 4.5 [2.17 Nesting of Regions]
4810       // The region associated with the distribute construct must be strictly
4811       // nested inside a teams region
4812       NestingProhibited =
4813           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4814       Recommend = ShouldBeInTeamsRegion;
4815     }
4816     if (!NestingProhibited &&
4817         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4818          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4819       // OpenMP 4.5 [2.17 Nesting of Regions]
4820       // If a target, target update, target data, target enter data, or
4821       // target exit data construct is encountered during execution of a
4822       // target region, the behavior is unspecified.
4823       NestingProhibited = Stack->hasDirective(
4824           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4825                              SourceLocation) {
4826             if (isOpenMPTargetExecutionDirective(K)) {
4827               OffendingRegion = K;
4828               return true;
4829             }
4830             return false;
4831           },
4832           false /* don't skip top directive */);
4833       CloseNesting = false;
4834     }
4835     if (NestingProhibited) {
4836       if (OrphanSeen) {
4837         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4838             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4839       } else {
4840         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4841             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4842             << Recommend << getOpenMPDirectiveName(CurrentRegion);
4843       }
4844       return true;
4845     }
4846   }
4847   return false;
4848 }
4849 
4850 struct Kind2Unsigned {
4851   using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4852   unsigned operator()(argument_type DK) { return unsigned(DK); }
4853 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4854 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4855                            ArrayRef<OMPClause *> Clauses,
4856                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4857   bool ErrorFound = false;
4858   unsigned NamedModifiersNumber = 0;
4859   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4860   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4861   SmallVector<SourceLocation, 4> NameModifierLoc;
4862   for (const OMPClause *C : Clauses) {
4863     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4864       // At most one if clause without a directive-name-modifier can appear on
4865       // the directive.
4866       OpenMPDirectiveKind CurNM = IC->getNameModifier();
4867       if (FoundNameModifiers[CurNM]) {
4868         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4869             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4870             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4871         ErrorFound = true;
4872       } else if (CurNM != OMPD_unknown) {
4873         NameModifierLoc.push_back(IC->getNameModifierLoc());
4874         ++NamedModifiersNumber;
4875       }
4876       FoundNameModifiers[CurNM] = IC;
4877       if (CurNM == OMPD_unknown)
4878         continue;
4879       // Check if the specified name modifier is allowed for the current
4880       // directive.
4881       // At most one if clause with the particular directive-name-modifier can
4882       // appear on the directive.
4883       bool MatchFound = false;
4884       for (auto NM : AllowedNameModifiers) {
4885         if (CurNM == NM) {
4886           MatchFound = true;
4887           break;
4888         }
4889       }
4890       if (!MatchFound) {
4891         S.Diag(IC->getNameModifierLoc(),
4892                diag::err_omp_wrong_if_directive_name_modifier)
4893             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4894         ErrorFound = true;
4895       }
4896     }
4897   }
4898   // If any if clause on the directive includes a directive-name-modifier then
4899   // all if clauses on the directive must include a directive-name-modifier.
4900   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4901     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4902       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4903              diag::err_omp_no_more_if_clause);
4904     } else {
4905       std::string Values;
4906       std::string Sep(", ");
4907       unsigned AllowedCnt = 0;
4908       unsigned TotalAllowedNum =
4909           AllowedNameModifiers.size() - NamedModifiersNumber;
4910       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4911            ++Cnt) {
4912         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4913         if (!FoundNameModifiers[NM]) {
4914           Values += "'";
4915           Values += getOpenMPDirectiveName(NM);
4916           Values += "'";
4917           if (AllowedCnt + 2 == TotalAllowedNum)
4918             Values += " or ";
4919           else if (AllowedCnt + 1 != TotalAllowedNum)
4920             Values += Sep;
4921           ++AllowedCnt;
4922         }
4923       }
4924       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4925              diag::err_omp_unnamed_if_clause)
4926           << (TotalAllowedNum > 1) << Values;
4927     }
4928     for (SourceLocation Loc : NameModifierLoc) {
4929       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4930     }
4931     ErrorFound = true;
4932   }
4933   return ErrorFound;
4934 }
4935 
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)4936 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4937                                                    SourceLocation &ELoc,
4938                                                    SourceRange &ERange,
4939                                                    bool AllowArraySection) {
4940   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4941       RefExpr->containsUnexpandedParameterPack())
4942     return std::make_pair(nullptr, true);
4943 
4944   // OpenMP [3.1, C/C++]
4945   //  A list item is a variable name.
4946   // OpenMP  [2.9.3.3, Restrictions, p.1]
4947   //  A variable that is part of another variable (as an array or
4948   //  structure element) cannot appear in a private clause.
4949   RefExpr = RefExpr->IgnoreParens();
4950   enum {
4951     NoArrayExpr = -1,
4952     ArraySubscript = 0,
4953     OMPArraySection = 1
4954   } IsArrayExpr = NoArrayExpr;
4955   if (AllowArraySection) {
4956     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4957       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4958       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4959         Base = TempASE->getBase()->IgnoreParenImpCasts();
4960       RefExpr = Base;
4961       IsArrayExpr = ArraySubscript;
4962     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4963       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4964       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4965         Base = TempOASE->getBase()->IgnoreParenImpCasts();
4966       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4967         Base = TempASE->getBase()->IgnoreParenImpCasts();
4968       RefExpr = Base;
4969       IsArrayExpr = OMPArraySection;
4970     }
4971   }
4972   ELoc = RefExpr->getExprLoc();
4973   ERange = RefExpr->getSourceRange();
4974   RefExpr = RefExpr->IgnoreParenImpCasts();
4975   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4976   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4977   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4978       (S.getCurrentThisType().isNull() || !ME ||
4979        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4980        !isa<FieldDecl>(ME->getMemberDecl()))) {
4981     if (IsArrayExpr != NoArrayExpr) {
4982       S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4983                                                          << ERange;
4984     } else {
4985       S.Diag(ELoc,
4986              AllowArraySection
4987                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
4988                  : diag::err_omp_expected_var_name_member_expr)
4989           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4990     }
4991     return std::make_pair(nullptr, false);
4992   }
4993   return std::make_pair(
4994       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4995 }
4996 
4997 namespace {
4998 /// Checks if the allocator is used in uses_allocators clause to be allowed in
4999 /// target regions.
5000 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5001   DSAStackTy *S = nullptr;
5002 
5003 public:
VisitDeclRefExpr(const DeclRefExpr * E)5004   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5005     return S->isUsesAllocatorsDecl(E->getDecl())
5006                .getValueOr(
5007                    DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5008            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5009   }
VisitStmt(const Stmt * S)5010   bool VisitStmt(const Stmt *S) {
5011     for (const Stmt *Child : S->children()) {
5012       if (Child && Visit(Child))
5013         return true;
5014     }
5015     return false;
5016   }
AllocatorChecker(DSAStackTy * S)5017   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5018 };
5019 } // namespace
5020 
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5021 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5022                                  ArrayRef<OMPClause *> Clauses) {
5023   assert(!S.CurContext->isDependentContext() &&
5024          "Expected non-dependent context.");
5025   auto AllocateRange =
5026       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5027   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5028       DeclToCopy;
5029   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5030     return isOpenMPPrivate(C->getClauseKind());
5031   });
5032   for (OMPClause *Cl : PrivateRange) {
5033     MutableArrayRef<Expr *>::iterator I, It, Et;
5034     if (Cl->getClauseKind() == OMPC_private) {
5035       auto *PC = cast<OMPPrivateClause>(Cl);
5036       I = PC->private_copies().begin();
5037       It = PC->varlist_begin();
5038       Et = PC->varlist_end();
5039     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5040       auto *PC = cast<OMPFirstprivateClause>(Cl);
5041       I = PC->private_copies().begin();
5042       It = PC->varlist_begin();
5043       Et = PC->varlist_end();
5044     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5045       auto *PC = cast<OMPLastprivateClause>(Cl);
5046       I = PC->private_copies().begin();
5047       It = PC->varlist_begin();
5048       Et = PC->varlist_end();
5049     } else if (Cl->getClauseKind() == OMPC_linear) {
5050       auto *PC = cast<OMPLinearClause>(Cl);
5051       I = PC->privates().begin();
5052       It = PC->varlist_begin();
5053       Et = PC->varlist_end();
5054     } else if (Cl->getClauseKind() == OMPC_reduction) {
5055       auto *PC = cast<OMPReductionClause>(Cl);
5056       I = PC->privates().begin();
5057       It = PC->varlist_begin();
5058       Et = PC->varlist_end();
5059     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5060       auto *PC = cast<OMPTaskReductionClause>(Cl);
5061       I = PC->privates().begin();
5062       It = PC->varlist_begin();
5063       Et = PC->varlist_end();
5064     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5065       auto *PC = cast<OMPInReductionClause>(Cl);
5066       I = PC->privates().begin();
5067       It = PC->varlist_begin();
5068       Et = PC->varlist_end();
5069     } else {
5070       llvm_unreachable("Expected private clause.");
5071     }
5072     for (Expr *E : llvm::make_range(It, Et)) {
5073       if (!*I) {
5074         ++I;
5075         continue;
5076       }
5077       SourceLocation ELoc;
5078       SourceRange ERange;
5079       Expr *SimpleRefExpr = E;
5080       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5081                                 /*AllowArraySection=*/true);
5082       DeclToCopy.try_emplace(Res.first,
5083                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5084       ++I;
5085     }
5086   }
5087   for (OMPClause *C : AllocateRange) {
5088     auto *AC = cast<OMPAllocateClause>(C);
5089     if (S.getLangOpts().OpenMP >= 50 &&
5090         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5091         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5092         AC->getAllocator()) {
5093       Expr *Allocator = AC->getAllocator();
5094       // OpenMP, 2.12.5 target Construct
5095       // Memory allocators that do not appear in a uses_allocators clause cannot
5096       // appear as an allocator in an allocate clause or be used in the target
5097       // region unless a requires directive with the dynamic_allocators clause
5098       // is present in the same compilation unit.
5099       AllocatorChecker Checker(Stack);
5100       if (Checker.Visit(Allocator))
5101         S.Diag(Allocator->getExprLoc(),
5102                diag::err_omp_allocator_not_in_uses_allocators)
5103             << Allocator->getSourceRange();
5104     }
5105     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5106         getAllocatorKind(S, Stack, AC->getAllocator());
5107     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5108     // For task, taskloop or target directives, allocation requests to memory
5109     // allocators with the trait access set to thread result in unspecified
5110     // behavior.
5111     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5112         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5113          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5114       S.Diag(AC->getAllocator()->getExprLoc(),
5115              diag::warn_omp_allocate_thread_on_task_target_directive)
5116           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5117     }
5118     for (Expr *E : AC->varlists()) {
5119       SourceLocation ELoc;
5120       SourceRange ERange;
5121       Expr *SimpleRefExpr = E;
5122       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5123       ValueDecl *VD = Res.first;
5124       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5125       if (!isOpenMPPrivate(Data.CKind)) {
5126         S.Diag(E->getExprLoc(),
5127                diag::err_omp_expected_private_copy_for_allocate);
5128         continue;
5129       }
5130       VarDecl *PrivateVD = DeclToCopy[VD];
5131       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5132                                             AllocatorKind, AC->getAllocator()))
5133         continue;
5134       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5135                                 E->getSourceRange());
5136     }
5137   }
5138 }
5139 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5140 StmtResult Sema::ActOnOpenMPExecutableDirective(
5141     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5142     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5143     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5144   StmtResult Res = StmtError();
5145   // First check CancelRegion which is then used in checkNestingOfRegions.
5146   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5147       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5148                             StartLoc))
5149     return StmtError();
5150 
5151   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5152   VarsWithInheritedDSAType VarsWithInheritedDSA;
5153   bool ErrorFound = false;
5154   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5155   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5156       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5157     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5158 
5159     // Check default data sharing attributes for referenced variables.
5160     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5161     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5162     Stmt *S = AStmt;
5163     while (--ThisCaptureLevel >= 0)
5164       S = cast<CapturedStmt>(S)->getCapturedStmt();
5165     DSAChecker.Visit(S);
5166     if (!isOpenMPTargetDataManagementDirective(Kind) &&
5167         !isOpenMPTaskingDirective(Kind)) {
5168       // Visit subcaptures to generate implicit clauses for captured vars.
5169       auto *CS = cast<CapturedStmt>(AStmt);
5170       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5171       getOpenMPCaptureRegions(CaptureRegions, Kind);
5172       // Ignore outer tasking regions for target directives.
5173       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5174         CS = cast<CapturedStmt>(CS->getCapturedStmt());
5175       DSAChecker.visitSubCaptures(CS);
5176     }
5177     if (DSAChecker.isErrorFound())
5178       return StmtError();
5179     // Generate list of implicitly defined firstprivate variables.
5180     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5181 
5182     SmallVector<Expr *, 4> ImplicitFirstprivates(
5183         DSAChecker.getImplicitFirstprivate().begin(),
5184         DSAChecker.getImplicitFirstprivate().end());
5185     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5186     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5187     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5188         ImplicitMapModifiers[DefaultmapKindNum];
5189     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5190         ImplicitMapModifiersLoc[DefaultmapKindNum];
5191     // Get the original location of present modifier from Defaultmap clause.
5192     SourceLocation PresentModifierLocs[DefaultmapKindNum];
5193     for (OMPClause *C : Clauses) {
5194       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5195         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5196           PresentModifierLocs[DMC->getDefaultmapKind()] =
5197               DMC->getDefaultmapModifierLoc();
5198     }
5199     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5200       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5201       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5202         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5203             Kind, static_cast<OpenMPMapClauseKind>(I));
5204         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5205       }
5206       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5207           DSAChecker.getImplicitMapModifier(Kind);
5208       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5209                                       ImplicitModifier.end());
5210       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5211                   ImplicitModifier.size(), PresentModifierLocs[VC]);
5212     }
5213     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5214     for (OMPClause *C : Clauses) {
5215       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5216         for (Expr *E : IRC->taskgroup_descriptors())
5217           if (E)
5218             ImplicitFirstprivates.emplace_back(E);
5219       }
5220       // OpenMP 5.0, 2.10.1 task Construct
5221       // [detach clause]... The event-handle will be considered as if it was
5222       // specified on a firstprivate clause.
5223       if (auto *DC = dyn_cast<OMPDetachClause>(C))
5224         ImplicitFirstprivates.push_back(DC->getEventHandler());
5225     }
5226     if (!ImplicitFirstprivates.empty()) {
5227       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5228               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5229               SourceLocation())) {
5230         ClausesWithImplicit.push_back(Implicit);
5231         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5232                      ImplicitFirstprivates.size();
5233       } else {
5234         ErrorFound = true;
5235       }
5236     }
5237     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5238       int ClauseKindCnt = -1;
5239       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5240         ++ClauseKindCnt;
5241         if (ImplicitMap.empty())
5242           continue;
5243         CXXScopeSpec MapperIdScopeSpec;
5244         DeclarationNameInfo MapperId;
5245         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5246         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5247                 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5248                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5249                 SourceLocation(), SourceLocation(), ImplicitMap,
5250                 OMPVarListLocTy())) {
5251           ClausesWithImplicit.emplace_back(Implicit);
5252           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5253                         ImplicitMap.size();
5254         } else {
5255           ErrorFound = true;
5256         }
5257       }
5258     }
5259   }
5260 
5261   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5262   switch (Kind) {
5263   case OMPD_parallel:
5264     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5265                                        EndLoc);
5266     AllowedNameModifiers.push_back(OMPD_parallel);
5267     break;
5268   case OMPD_simd:
5269     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5270                                    VarsWithInheritedDSA);
5271     if (LangOpts.OpenMP >= 50)
5272       AllowedNameModifiers.push_back(OMPD_simd);
5273     break;
5274   case OMPD_for:
5275     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5276                                   VarsWithInheritedDSA);
5277     break;
5278   case OMPD_for_simd:
5279     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5280                                       EndLoc, VarsWithInheritedDSA);
5281     if (LangOpts.OpenMP >= 50)
5282       AllowedNameModifiers.push_back(OMPD_simd);
5283     break;
5284   case OMPD_sections:
5285     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5286                                        EndLoc);
5287     break;
5288   case OMPD_section:
5289     assert(ClausesWithImplicit.empty() &&
5290            "No clauses are allowed for 'omp section' directive");
5291     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5292     break;
5293   case OMPD_single:
5294     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5295                                      EndLoc);
5296     break;
5297   case OMPD_master:
5298     assert(ClausesWithImplicit.empty() &&
5299            "No clauses are allowed for 'omp master' directive");
5300     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5301     break;
5302   case OMPD_critical:
5303     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5304                                        StartLoc, EndLoc);
5305     break;
5306   case OMPD_parallel_for:
5307     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5308                                           EndLoc, VarsWithInheritedDSA);
5309     AllowedNameModifiers.push_back(OMPD_parallel);
5310     break;
5311   case OMPD_parallel_for_simd:
5312     Res = ActOnOpenMPParallelForSimdDirective(
5313         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5314     AllowedNameModifiers.push_back(OMPD_parallel);
5315     if (LangOpts.OpenMP >= 50)
5316       AllowedNameModifiers.push_back(OMPD_simd);
5317     break;
5318   case OMPD_parallel_master:
5319     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5320                                                StartLoc, EndLoc);
5321     AllowedNameModifiers.push_back(OMPD_parallel);
5322     break;
5323   case OMPD_parallel_sections:
5324     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5325                                                StartLoc, EndLoc);
5326     AllowedNameModifiers.push_back(OMPD_parallel);
5327     break;
5328   case OMPD_task:
5329     Res =
5330         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5331     AllowedNameModifiers.push_back(OMPD_task);
5332     break;
5333   case OMPD_taskyield:
5334     assert(ClausesWithImplicit.empty() &&
5335            "No clauses are allowed for 'omp taskyield' directive");
5336     assert(AStmt == nullptr &&
5337            "No associated statement allowed for 'omp taskyield' directive");
5338     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5339     break;
5340   case OMPD_barrier:
5341     assert(ClausesWithImplicit.empty() &&
5342            "No clauses are allowed for 'omp barrier' directive");
5343     assert(AStmt == nullptr &&
5344            "No associated statement allowed for 'omp barrier' directive");
5345     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5346     break;
5347   case OMPD_taskwait:
5348     assert(ClausesWithImplicit.empty() &&
5349            "No clauses are allowed for 'omp taskwait' directive");
5350     assert(AStmt == nullptr &&
5351            "No associated statement allowed for 'omp taskwait' directive");
5352     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5353     break;
5354   case OMPD_taskgroup:
5355     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5356                                         EndLoc);
5357     break;
5358   case OMPD_flush:
5359     assert(AStmt == nullptr &&
5360            "No associated statement allowed for 'omp flush' directive");
5361     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5362     break;
5363   case OMPD_depobj:
5364     assert(AStmt == nullptr &&
5365            "No associated statement allowed for 'omp depobj' directive");
5366     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5367     break;
5368   case OMPD_scan:
5369     assert(AStmt == nullptr &&
5370            "No associated statement allowed for 'omp scan' directive");
5371     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5372     break;
5373   case OMPD_ordered:
5374     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5375                                       EndLoc);
5376     break;
5377   case OMPD_atomic:
5378     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5379                                      EndLoc);
5380     break;
5381   case OMPD_teams:
5382     Res =
5383         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5384     break;
5385   case OMPD_target:
5386     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5387                                      EndLoc);
5388     AllowedNameModifiers.push_back(OMPD_target);
5389     break;
5390   case OMPD_target_parallel:
5391     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5392                                              StartLoc, EndLoc);
5393     AllowedNameModifiers.push_back(OMPD_target);
5394     AllowedNameModifiers.push_back(OMPD_parallel);
5395     break;
5396   case OMPD_target_parallel_for:
5397     Res = ActOnOpenMPTargetParallelForDirective(
5398         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5399     AllowedNameModifiers.push_back(OMPD_target);
5400     AllowedNameModifiers.push_back(OMPD_parallel);
5401     break;
5402   case OMPD_cancellation_point:
5403     assert(ClausesWithImplicit.empty() &&
5404            "No clauses are allowed for 'omp cancellation point' directive");
5405     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5406                                "cancellation point' directive");
5407     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5408     break;
5409   case OMPD_cancel:
5410     assert(AStmt == nullptr &&
5411            "No associated statement allowed for 'omp cancel' directive");
5412     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5413                                      CancelRegion);
5414     AllowedNameModifiers.push_back(OMPD_cancel);
5415     break;
5416   case OMPD_target_data:
5417     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5418                                          EndLoc);
5419     AllowedNameModifiers.push_back(OMPD_target_data);
5420     break;
5421   case OMPD_target_enter_data:
5422     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5423                                               EndLoc, AStmt);
5424     AllowedNameModifiers.push_back(OMPD_target_enter_data);
5425     break;
5426   case OMPD_target_exit_data:
5427     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5428                                              EndLoc, AStmt);
5429     AllowedNameModifiers.push_back(OMPD_target_exit_data);
5430     break;
5431   case OMPD_taskloop:
5432     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5433                                        EndLoc, VarsWithInheritedDSA);
5434     AllowedNameModifiers.push_back(OMPD_taskloop);
5435     break;
5436   case OMPD_taskloop_simd:
5437     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5438                                            EndLoc, VarsWithInheritedDSA);
5439     AllowedNameModifiers.push_back(OMPD_taskloop);
5440     if (LangOpts.OpenMP >= 50)
5441       AllowedNameModifiers.push_back(OMPD_simd);
5442     break;
5443   case OMPD_master_taskloop:
5444     Res = ActOnOpenMPMasterTaskLoopDirective(
5445         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5446     AllowedNameModifiers.push_back(OMPD_taskloop);
5447     break;
5448   case OMPD_master_taskloop_simd:
5449     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5450         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5451     AllowedNameModifiers.push_back(OMPD_taskloop);
5452     if (LangOpts.OpenMP >= 50)
5453       AllowedNameModifiers.push_back(OMPD_simd);
5454     break;
5455   case OMPD_parallel_master_taskloop:
5456     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5457         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5458     AllowedNameModifiers.push_back(OMPD_taskloop);
5459     AllowedNameModifiers.push_back(OMPD_parallel);
5460     break;
5461   case OMPD_parallel_master_taskloop_simd:
5462     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5463         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5464     AllowedNameModifiers.push_back(OMPD_taskloop);
5465     AllowedNameModifiers.push_back(OMPD_parallel);
5466     if (LangOpts.OpenMP >= 50)
5467       AllowedNameModifiers.push_back(OMPD_simd);
5468     break;
5469   case OMPD_distribute:
5470     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5471                                          EndLoc, VarsWithInheritedDSA);
5472     break;
5473   case OMPD_target_update:
5474     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5475                                            EndLoc, AStmt);
5476     AllowedNameModifiers.push_back(OMPD_target_update);
5477     break;
5478   case OMPD_distribute_parallel_for:
5479     Res = ActOnOpenMPDistributeParallelForDirective(
5480         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5481     AllowedNameModifiers.push_back(OMPD_parallel);
5482     break;
5483   case OMPD_distribute_parallel_for_simd:
5484     Res = ActOnOpenMPDistributeParallelForSimdDirective(
5485         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5486     AllowedNameModifiers.push_back(OMPD_parallel);
5487     if (LangOpts.OpenMP >= 50)
5488       AllowedNameModifiers.push_back(OMPD_simd);
5489     break;
5490   case OMPD_distribute_simd:
5491     Res = ActOnOpenMPDistributeSimdDirective(
5492         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5493     if (LangOpts.OpenMP >= 50)
5494       AllowedNameModifiers.push_back(OMPD_simd);
5495     break;
5496   case OMPD_target_parallel_for_simd:
5497     Res = ActOnOpenMPTargetParallelForSimdDirective(
5498         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5499     AllowedNameModifiers.push_back(OMPD_target);
5500     AllowedNameModifiers.push_back(OMPD_parallel);
5501     if (LangOpts.OpenMP >= 50)
5502       AllowedNameModifiers.push_back(OMPD_simd);
5503     break;
5504   case OMPD_target_simd:
5505     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5506                                          EndLoc, VarsWithInheritedDSA);
5507     AllowedNameModifiers.push_back(OMPD_target);
5508     if (LangOpts.OpenMP >= 50)
5509       AllowedNameModifiers.push_back(OMPD_simd);
5510     break;
5511   case OMPD_teams_distribute:
5512     Res = ActOnOpenMPTeamsDistributeDirective(
5513         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5514     break;
5515   case OMPD_teams_distribute_simd:
5516     Res = ActOnOpenMPTeamsDistributeSimdDirective(
5517         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5518     if (LangOpts.OpenMP >= 50)
5519       AllowedNameModifiers.push_back(OMPD_simd);
5520     break;
5521   case OMPD_teams_distribute_parallel_for_simd:
5522     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5523         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5524     AllowedNameModifiers.push_back(OMPD_parallel);
5525     if (LangOpts.OpenMP >= 50)
5526       AllowedNameModifiers.push_back(OMPD_simd);
5527     break;
5528   case OMPD_teams_distribute_parallel_for:
5529     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5530         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5531     AllowedNameModifiers.push_back(OMPD_parallel);
5532     break;
5533   case OMPD_target_teams:
5534     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5535                                           EndLoc);
5536     AllowedNameModifiers.push_back(OMPD_target);
5537     break;
5538   case OMPD_target_teams_distribute:
5539     Res = ActOnOpenMPTargetTeamsDistributeDirective(
5540         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5541     AllowedNameModifiers.push_back(OMPD_target);
5542     break;
5543   case OMPD_target_teams_distribute_parallel_for:
5544     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5545         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5546     AllowedNameModifiers.push_back(OMPD_target);
5547     AllowedNameModifiers.push_back(OMPD_parallel);
5548     break;
5549   case OMPD_target_teams_distribute_parallel_for_simd:
5550     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5551         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5552     AllowedNameModifiers.push_back(OMPD_target);
5553     AllowedNameModifiers.push_back(OMPD_parallel);
5554     if (LangOpts.OpenMP >= 50)
5555       AllowedNameModifiers.push_back(OMPD_simd);
5556     break;
5557   case OMPD_target_teams_distribute_simd:
5558     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5559         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5560     AllowedNameModifiers.push_back(OMPD_target);
5561     if (LangOpts.OpenMP >= 50)
5562       AllowedNameModifiers.push_back(OMPD_simd);
5563     break;
5564   case OMPD_declare_target:
5565   case OMPD_end_declare_target:
5566   case OMPD_threadprivate:
5567   case OMPD_allocate:
5568   case OMPD_declare_reduction:
5569   case OMPD_declare_mapper:
5570   case OMPD_declare_simd:
5571   case OMPD_requires:
5572   case OMPD_declare_variant:
5573   case OMPD_begin_declare_variant:
5574   case OMPD_end_declare_variant:
5575     llvm_unreachable("OpenMP Directive is not allowed");
5576   case OMPD_unknown:
5577   default:
5578     llvm_unreachable("Unknown OpenMP directive");
5579   }
5580 
5581   ErrorFound = Res.isInvalid() || ErrorFound;
5582 
5583   // Check variables in the clauses if default(none) or
5584   // default(firstprivate) was specified.
5585   if (DSAStack->getDefaultDSA() == DSA_none ||
5586       DSAStack->getDefaultDSA() == DSA_firstprivate) {
5587     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
5588     for (OMPClause *C : Clauses) {
5589       switch (C->getClauseKind()) {
5590       case OMPC_num_threads:
5591       case OMPC_dist_schedule:
5592         // Do not analyse if no parent teams directive.
5593         if (isOpenMPTeamsDirective(Kind))
5594           break;
5595         continue;
5596       case OMPC_if:
5597         if (isOpenMPTeamsDirective(Kind) &&
5598             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5599           break;
5600         if (isOpenMPParallelDirective(Kind) &&
5601             isOpenMPTaskLoopDirective(Kind) &&
5602             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5603           break;
5604         continue;
5605       case OMPC_schedule:
5606       case OMPC_detach:
5607         break;
5608       case OMPC_grainsize:
5609       case OMPC_num_tasks:
5610       case OMPC_final:
5611       case OMPC_priority:
5612         // Do not analyze if no parent parallel directive.
5613         if (isOpenMPParallelDirective(Kind))
5614           break;
5615         continue;
5616       case OMPC_ordered:
5617       case OMPC_device:
5618       case OMPC_num_teams:
5619       case OMPC_thread_limit:
5620       case OMPC_hint:
5621       case OMPC_collapse:
5622       case OMPC_safelen:
5623       case OMPC_simdlen:
5624       case OMPC_default:
5625       case OMPC_proc_bind:
5626       case OMPC_private:
5627       case OMPC_firstprivate:
5628       case OMPC_lastprivate:
5629       case OMPC_shared:
5630       case OMPC_reduction:
5631       case OMPC_task_reduction:
5632       case OMPC_in_reduction:
5633       case OMPC_linear:
5634       case OMPC_aligned:
5635       case OMPC_copyin:
5636       case OMPC_copyprivate:
5637       case OMPC_nowait:
5638       case OMPC_untied:
5639       case OMPC_mergeable:
5640       case OMPC_allocate:
5641       case OMPC_read:
5642       case OMPC_write:
5643       case OMPC_update:
5644       case OMPC_capture:
5645       case OMPC_seq_cst:
5646       case OMPC_acq_rel:
5647       case OMPC_acquire:
5648       case OMPC_release:
5649       case OMPC_relaxed:
5650       case OMPC_depend:
5651       case OMPC_threads:
5652       case OMPC_simd:
5653       case OMPC_map:
5654       case OMPC_nogroup:
5655       case OMPC_defaultmap:
5656       case OMPC_to:
5657       case OMPC_from:
5658       case OMPC_use_device_ptr:
5659       case OMPC_use_device_addr:
5660       case OMPC_is_device_ptr:
5661       case OMPC_nontemporal:
5662       case OMPC_order:
5663       case OMPC_destroy:
5664       case OMPC_inclusive:
5665       case OMPC_exclusive:
5666       case OMPC_uses_allocators:
5667       case OMPC_affinity:
5668         continue;
5669       case OMPC_allocator:
5670       case OMPC_flush:
5671       case OMPC_depobj:
5672       case OMPC_threadprivate:
5673       case OMPC_uniform:
5674       case OMPC_unknown:
5675       case OMPC_unified_address:
5676       case OMPC_unified_shared_memory:
5677       case OMPC_reverse_offload:
5678       case OMPC_dynamic_allocators:
5679       case OMPC_atomic_default_mem_order:
5680       case OMPC_device_type:
5681       case OMPC_match:
5682       default:
5683         llvm_unreachable("Unexpected clause");
5684       }
5685       for (Stmt *CC : C->children()) {
5686         if (CC)
5687           DSAChecker.Visit(CC);
5688       }
5689     }
5690     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5691       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5692   }
5693   for (const auto &P : VarsWithInheritedDSA) {
5694     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5695       continue;
5696     ErrorFound = true;
5697     if (DSAStack->getDefaultDSA() == DSA_none ||
5698         DSAStack->getDefaultDSA() == DSA_firstprivate) {
5699       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5700           << P.first << P.second->getSourceRange();
5701       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5702     } else if (getLangOpts().OpenMP >= 50) {
5703       Diag(P.second->getExprLoc(),
5704            diag::err_omp_defaultmap_no_attr_for_variable)
5705           << P.first << P.second->getSourceRange();
5706       Diag(DSAStack->getDefaultDSALocation(),
5707            diag::note_omp_defaultmap_attr_none);
5708     }
5709   }
5710 
5711   if (!AllowedNameModifiers.empty())
5712     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5713                  ErrorFound;
5714 
5715   if (ErrorFound)
5716     return StmtError();
5717 
5718   if (!CurContext->isDependentContext() &&
5719       isOpenMPTargetExecutionDirective(Kind) &&
5720       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5721         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5722         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5723         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5724     // Register target to DSA Stack.
5725     DSAStack->addTargetDirLocation(StartLoc);
5726   }
5727 
5728   return Res;
5729 }
5730 
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)5731 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5732     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5733     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5734     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5735     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5736   assert(Aligneds.size() == Alignments.size());
5737   assert(Linears.size() == LinModifiers.size());
5738   assert(Linears.size() == Steps.size());
5739   if (!DG || DG.get().isNull())
5740     return DeclGroupPtrTy();
5741 
5742   const int SimdId = 0;
5743   if (!DG.get().isSingleDecl()) {
5744     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5745         << SimdId;
5746     return DG;
5747   }
5748   Decl *ADecl = DG.get().getSingleDecl();
5749   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5750     ADecl = FTD->getTemplatedDecl();
5751 
5752   auto *FD = dyn_cast<FunctionDecl>(ADecl);
5753   if (!FD) {
5754     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5755     return DeclGroupPtrTy();
5756   }
5757 
5758   // OpenMP [2.8.2, declare simd construct, Description]
5759   // The parameter of the simdlen clause must be a constant positive integer
5760   // expression.
5761   ExprResult SL;
5762   if (Simdlen)
5763     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5764   // OpenMP [2.8.2, declare simd construct, Description]
5765   // The special this pointer can be used as if was one of the arguments to the
5766   // function in any of the linear, aligned, or uniform clauses.
5767   // The uniform clause declares one or more arguments to have an invariant
5768   // value for all concurrent invocations of the function in the execution of a
5769   // single SIMD loop.
5770   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5771   const Expr *UniformedLinearThis = nullptr;
5772   for (const Expr *E : Uniforms) {
5773     E = E->IgnoreParenImpCasts();
5774     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5775       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5776         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5777             FD->getParamDecl(PVD->getFunctionScopeIndex())
5778                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5779           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5780           continue;
5781         }
5782     if (isa<CXXThisExpr>(E)) {
5783       UniformedLinearThis = E;
5784       continue;
5785     }
5786     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5787         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5788   }
5789   // OpenMP [2.8.2, declare simd construct, Description]
5790   // The aligned clause declares that the object to which each list item points
5791   // is aligned to the number of bytes expressed in the optional parameter of
5792   // the aligned clause.
5793   // The special this pointer can be used as if was one of the arguments to the
5794   // function in any of the linear, aligned, or uniform clauses.
5795   // The type of list items appearing in the aligned clause must be array,
5796   // pointer, reference to array, or reference to pointer.
5797   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5798   const Expr *AlignedThis = nullptr;
5799   for (const Expr *E : Aligneds) {
5800     E = E->IgnoreParenImpCasts();
5801     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5802       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5803         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5804         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5805             FD->getParamDecl(PVD->getFunctionScopeIndex())
5806                     ->getCanonicalDecl() == CanonPVD) {
5807           // OpenMP  [2.8.1, simd construct, Restrictions]
5808           // A list-item cannot appear in more than one aligned clause.
5809           if (AlignedArgs.count(CanonPVD) > 0) {
5810             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5811                 << 1 << getOpenMPClauseName(OMPC_aligned)
5812                 << E->getSourceRange();
5813             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5814                  diag::note_omp_explicit_dsa)
5815                 << getOpenMPClauseName(OMPC_aligned);
5816             continue;
5817           }
5818           AlignedArgs[CanonPVD] = E;
5819           QualType QTy = PVD->getType()
5820                              .getNonReferenceType()
5821                              .getUnqualifiedType()
5822                              .getCanonicalType();
5823           const Type *Ty = QTy.getTypePtrOrNull();
5824           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5825             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5826                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5827             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5828           }
5829           continue;
5830         }
5831       }
5832     if (isa<CXXThisExpr>(E)) {
5833       if (AlignedThis) {
5834         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5835             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5836         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5837             << getOpenMPClauseName(OMPC_aligned);
5838       }
5839       AlignedThis = E;
5840       continue;
5841     }
5842     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5843         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5844   }
5845   // The optional parameter of the aligned clause, alignment, must be a constant
5846   // positive integer expression. If no optional parameter is specified,
5847   // implementation-defined default alignments for SIMD instructions on the
5848   // target platforms are assumed.
5849   SmallVector<const Expr *, 4> NewAligns;
5850   for (Expr *E : Alignments) {
5851     ExprResult Align;
5852     if (E)
5853       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5854     NewAligns.push_back(Align.get());
5855   }
5856   // OpenMP [2.8.2, declare simd construct, Description]
5857   // The linear clause declares one or more list items to be private to a SIMD
5858   // lane and to have a linear relationship with respect to the iteration space
5859   // of a loop.
5860   // The special this pointer can be used as if was one of the arguments to the
5861   // function in any of the linear, aligned, or uniform clauses.
5862   // When a linear-step expression is specified in a linear clause it must be
5863   // either a constant integer expression or an integer-typed parameter that is
5864   // specified in a uniform clause on the directive.
5865   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5866   const bool IsUniformedThis = UniformedLinearThis != nullptr;
5867   auto MI = LinModifiers.begin();
5868   for (const Expr *E : Linears) {
5869     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5870     ++MI;
5871     E = E->IgnoreParenImpCasts();
5872     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5873       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5874         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5875         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5876             FD->getParamDecl(PVD->getFunctionScopeIndex())
5877                     ->getCanonicalDecl() == CanonPVD) {
5878           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
5879           // A list-item cannot appear in more than one linear clause.
5880           if (LinearArgs.count(CanonPVD) > 0) {
5881             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5882                 << getOpenMPClauseName(OMPC_linear)
5883                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5884             Diag(LinearArgs[CanonPVD]->getExprLoc(),
5885                  diag::note_omp_explicit_dsa)
5886                 << getOpenMPClauseName(OMPC_linear);
5887             continue;
5888           }
5889           // Each argument can appear in at most one uniform or linear clause.
5890           if (UniformedArgs.count(CanonPVD) > 0) {
5891             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5892                 << getOpenMPClauseName(OMPC_linear)
5893                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5894             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5895                  diag::note_omp_explicit_dsa)
5896                 << getOpenMPClauseName(OMPC_uniform);
5897             continue;
5898           }
5899           LinearArgs[CanonPVD] = E;
5900           if (E->isValueDependent() || E->isTypeDependent() ||
5901               E->isInstantiationDependent() ||
5902               E->containsUnexpandedParameterPack())
5903             continue;
5904           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5905                                       PVD->getOriginalType(),
5906                                       /*IsDeclareSimd=*/true);
5907           continue;
5908         }
5909       }
5910     if (isa<CXXThisExpr>(E)) {
5911       if (UniformedLinearThis) {
5912         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5913             << getOpenMPClauseName(OMPC_linear)
5914             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5915             << E->getSourceRange();
5916         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5917             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5918                                                    : OMPC_linear);
5919         continue;
5920       }
5921       UniformedLinearThis = E;
5922       if (E->isValueDependent() || E->isTypeDependent() ||
5923           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5924         continue;
5925       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5926                                   E->getType(), /*IsDeclareSimd=*/true);
5927       continue;
5928     }
5929     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5930         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5931   }
5932   Expr *Step = nullptr;
5933   Expr *NewStep = nullptr;
5934   SmallVector<Expr *, 4> NewSteps;
5935   for (Expr *E : Steps) {
5936     // Skip the same step expression, it was checked already.
5937     if (Step == E || !E) {
5938       NewSteps.push_back(E ? NewStep : nullptr);
5939       continue;
5940     }
5941     Step = E;
5942     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5943       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5944         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5945         if (UniformedArgs.count(CanonPVD) == 0) {
5946           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5947               << Step->getSourceRange();
5948         } else if (E->isValueDependent() || E->isTypeDependent() ||
5949                    E->isInstantiationDependent() ||
5950                    E->containsUnexpandedParameterPack() ||
5951                    CanonPVD->getType()->hasIntegerRepresentation()) {
5952           NewSteps.push_back(Step);
5953         } else {
5954           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5955               << Step->getSourceRange();
5956         }
5957         continue;
5958       }
5959     NewStep = Step;
5960     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5961         !Step->isInstantiationDependent() &&
5962         !Step->containsUnexpandedParameterPack()) {
5963       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5964                     .get();
5965       if (NewStep)
5966         NewStep =
5967             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
5968     }
5969     NewSteps.push_back(NewStep);
5970   }
5971   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5972       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5973       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5974       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5975       const_cast<Expr **>(Linears.data()), Linears.size(),
5976       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5977       NewSteps.data(), NewSteps.size(), SR);
5978   ADecl->addAttr(NewAttr);
5979   return DG;
5980 }
5981 
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)5982 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5983                          QualType NewType) {
5984   assert(NewType->isFunctionProtoType() &&
5985          "Expected function type with prototype.");
5986   assert(FD->getType()->isFunctionNoProtoType() &&
5987          "Expected function with type with no prototype.");
5988   assert(FDWithProto->getType()->isFunctionProtoType() &&
5989          "Expected function with prototype.");
5990   // Synthesize parameters with the same types.
5991   FD->setType(NewType);
5992   SmallVector<ParmVarDecl *, 16> Params;
5993   for (const ParmVarDecl *P : FDWithProto->parameters()) {
5994     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5995                                       SourceLocation(), nullptr, P->getType(),
5996                                       /*TInfo=*/nullptr, SC_None, nullptr);
5997     Param->setScopeInfo(0, Params.size());
5998     Param->setImplicit();
5999     Params.push_back(Param);
6000   }
6001 
6002   FD->setParams(Params);
6003 }
6004 
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)6005 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6006   if (D->isInvalidDecl())
6007     return;
6008   FunctionDecl *FD = nullptr;
6009   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6010     FD = UTemplDecl->getTemplatedDecl();
6011   else
6012     FD = cast<FunctionDecl>(D);
6013   assert(FD && "Expected a function declaration!");
6014 
6015   // If we are intantiating templates we do *not* apply scoped assumptions but
6016   // only global ones. We apply scoped assumption to the template definition
6017   // though.
6018   if (!inTemplateInstantiation()) {
6019     for (AssumptionAttr *AA : OMPAssumeScoped)
6020       FD->addAttr(AA);
6021   }
6022   for (AssumptionAttr *AA : OMPAssumeGlobal)
6023     FD->addAttr(AA);
6024 }
6025 
OMPDeclareVariantScope(OMPTraitInfo & TI)6026 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6027     : TI(&TI), NameSuffix(TI.getMangledName()) {}
6028 
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)6029 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6030     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6031     SmallVectorImpl<FunctionDecl *> &Bases) {
6032   if (!D.getIdentifier())
6033     return;
6034 
6035   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6036 
6037   // Template specialization is an extension, check if we do it.
6038   bool IsTemplated = !TemplateParamLists.empty();
6039   if (IsTemplated &
6040       !DVScope.TI->isExtensionActive(
6041           llvm::omp::TraitProperty::implementation_extension_allow_templates))
6042     return;
6043 
6044   IdentifierInfo *BaseII = D.getIdentifier();
6045   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6046                       LookupOrdinaryName);
6047   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6048 
6049   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6050   QualType FType = TInfo->getType();
6051 
6052   bool IsConstexpr =
6053       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6054   bool IsConsteval =
6055       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6056 
6057   for (auto *Candidate : Lookup) {
6058     auto *CandidateDecl = Candidate->getUnderlyingDecl();
6059     FunctionDecl *UDecl = nullptr;
6060     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6061       UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6062     else if (!IsTemplated)
6063       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6064     if (!UDecl)
6065       continue;
6066 
6067     // Don't specialize constexpr/consteval functions with
6068     // non-constexpr/consteval functions.
6069     if (UDecl->isConstexpr() && !IsConstexpr)
6070       continue;
6071     if (UDecl->isConsteval() && !IsConsteval)
6072       continue;
6073 
6074     QualType UDeclTy = UDecl->getType();
6075     if (!UDeclTy->isDependentType()) {
6076       QualType NewType = Context.mergeFunctionTypes(
6077           FType, UDeclTy, /* OfBlockPointer */ false,
6078           /* Unqualified */ false, /* AllowCXX */ true);
6079       if (NewType.isNull())
6080         continue;
6081     }
6082 
6083     // Found a base!
6084     Bases.push_back(UDecl);
6085   }
6086 
6087   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6088       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6089   // If no base was found we create a declaration that we use as base.
6090   if (Bases.empty() && UseImplicitBase) {
6091     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6092     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6093     BaseD->setImplicit(true);
6094     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6095       Bases.push_back(BaseTemplD->getTemplatedDecl());
6096     else
6097       Bases.push_back(cast<FunctionDecl>(BaseD));
6098   }
6099 
6100   std::string MangledName;
6101   MangledName += D.getIdentifier()->getName();
6102   MangledName += getOpenMPVariantManglingSeparatorStr();
6103   MangledName += DVScope.NameSuffix;
6104   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6105 
6106   VariantII.setMangledOpenMPVariantName(true);
6107   D.SetIdentifier(&VariantII, D.getBeginLoc());
6108 }
6109 
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)6110 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6111     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6112   // Do not mark function as is used to prevent its emission if this is the
6113   // only place where it is used.
6114   EnterExpressionEvaluationContext Unevaluated(
6115       *this, Sema::ExpressionEvaluationContext::Unevaluated);
6116 
6117   FunctionDecl *FD = nullptr;
6118   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6119     FD = UTemplDecl->getTemplatedDecl();
6120   else
6121     FD = cast<FunctionDecl>(D);
6122   auto *VariantFuncRef = DeclRefExpr::Create(
6123       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6124       /* RefersToEnclosingVariableOrCapture */ false,
6125       /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6126 
6127   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6128   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6129       Context, VariantFuncRef, DVScope.TI);
6130   for (FunctionDecl *BaseFD : Bases)
6131     BaseFD->addAttr(OMPDeclareVariantA);
6132 }
6133 
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)6134 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6135                                  SourceLocation LParenLoc,
6136                                  MultiExprArg ArgExprs,
6137                                  SourceLocation RParenLoc, Expr *ExecConfig) {
6138   // The common case is a regular call we do not want to specialize at all. Try
6139   // to make that case fast by bailing early.
6140   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6141   if (!CE)
6142     return Call;
6143 
6144   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6145   if (!CalleeFnDecl)
6146     return Call;
6147 
6148   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6149     return Call;
6150 
6151   ASTContext &Context = getASTContext();
6152   std::function<void(StringRef)> DiagUnknownTrait = [this,
6153                                                      CE](StringRef ISATrait) {
6154     // TODO Track the selector locations in a way that is accessible here to
6155     // improve the diagnostic location.
6156     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6157         << ISATrait;
6158   };
6159   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6160                           getCurFunctionDecl());
6161 
6162   QualType CalleeFnType = CalleeFnDecl->getType();
6163 
6164   SmallVector<Expr *, 4> Exprs;
6165   SmallVector<VariantMatchInfo, 4> VMIs;
6166   while (CalleeFnDecl) {
6167     for (OMPDeclareVariantAttr *A :
6168          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6169       Expr *VariantRef = A->getVariantFuncRef();
6170 
6171       VariantMatchInfo VMI;
6172       OMPTraitInfo &TI = A->getTraitInfo();
6173       TI.getAsVariantMatchInfo(Context, VMI);
6174       if (!isVariantApplicableInContext(VMI, OMPCtx,
6175                                         /* DeviceSetOnly */ false))
6176         continue;
6177 
6178       VMIs.push_back(VMI);
6179       Exprs.push_back(VariantRef);
6180     }
6181 
6182     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6183   }
6184 
6185   ExprResult NewCall;
6186   do {
6187     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6188     if (BestIdx < 0)
6189       return Call;
6190     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6191     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6192 
6193     {
6194       // Try to build a (member) call expression for the current best applicable
6195       // variant expression. We allow this to fail in which case we continue
6196       // with the next best variant expression. The fail case is part of the
6197       // implementation defined behavior in the OpenMP standard when it talks
6198       // about what differences in the function prototypes: "Any differences
6199       // that the specific OpenMP context requires in the prototype of the
6200       // variant from the base function prototype are implementation defined."
6201       // This wording is there to allow the specialized variant to have a
6202       // different type than the base function. This is intended and OK but if
6203       // we cannot create a call the difference is not in the "implementation
6204       // defined range" we allow.
6205       Sema::TentativeAnalysisScope Trap(*this);
6206 
6207       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6208         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6209         BestExpr = MemberExpr::CreateImplicit(
6210             Context, MemberCall->getImplicitObjectArgument(),
6211             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6212             MemberCall->getValueKind(), MemberCall->getObjectKind());
6213       }
6214       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6215                               ExecConfig);
6216       if (NewCall.isUsable()) {
6217         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6218           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6219           QualType NewType = Context.mergeFunctionTypes(
6220               CalleeFnType, NewCalleeFnDecl->getType(),
6221               /* OfBlockPointer */ false,
6222               /* Unqualified */ false, /* AllowCXX */ true);
6223           if (!NewType.isNull())
6224             break;
6225           // Don't use the call if the function type was not compatible.
6226           NewCall = nullptr;
6227         }
6228       }
6229     }
6230 
6231     VMIs.erase(VMIs.begin() + BestIdx);
6232     Exprs.erase(Exprs.begin() + BestIdx);
6233   } while (!VMIs.empty());
6234 
6235   if (!NewCall.isUsable())
6236     return Call;
6237   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6238 }
6239 
6240 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6241 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6242                                         Expr *VariantRef, OMPTraitInfo &TI,
6243                                         SourceRange SR) {
6244   if (!DG || DG.get().isNull())
6245     return None;
6246 
6247   const int VariantId = 1;
6248   // Must be applied only to single decl.
6249   if (!DG.get().isSingleDecl()) {
6250     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6251         << VariantId << SR;
6252     return None;
6253   }
6254   Decl *ADecl = DG.get().getSingleDecl();
6255   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6256     ADecl = FTD->getTemplatedDecl();
6257 
6258   // Decl must be a function.
6259   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6260   if (!FD) {
6261     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6262         << VariantId << SR;
6263     return None;
6264   }
6265 
6266   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6267     return FD->hasAttrs() &&
6268            (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6269             FD->hasAttr<TargetAttr>());
6270   };
6271   // OpenMP is not compatible with CPU-specific attributes.
6272   if (HasMultiVersionAttributes(FD)) {
6273     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6274         << SR;
6275     return None;
6276   }
6277 
6278   // Allow #pragma omp declare variant only if the function is not used.
6279   if (FD->isUsed(false))
6280     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6281         << FD->getLocation();
6282 
6283   // Check if the function was emitted already.
6284   const FunctionDecl *Definition;
6285   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6286       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6287     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6288         << FD->getLocation();
6289 
6290   // The VariantRef must point to function.
6291   if (!VariantRef) {
6292     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6293     return None;
6294   }
6295 
6296   auto ShouldDelayChecks = [](Expr *&E, bool) {
6297     return E && (E->isTypeDependent() || E->isValueDependent() ||
6298                  E->containsUnexpandedParameterPack() ||
6299                  E->isInstantiationDependent());
6300   };
6301   // Do not check templates, wait until instantiation.
6302   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6303       TI.anyScoreOrCondition(ShouldDelayChecks))
6304     return std::make_pair(FD, VariantRef);
6305 
6306   // Deal with non-constant score and user condition expressions.
6307   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6308                                                      bool IsScore) -> bool {
6309     if (!E || E->isIntegerConstantExpr(Context))
6310       return false;
6311 
6312     if (IsScore) {
6313       // We warn on non-constant scores and pretend they were not present.
6314       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6315           << E;
6316       E = nullptr;
6317     } else {
6318       // We could replace a non-constant user condition with "false" but we
6319       // will soon need to handle these anyway for the dynamic version of
6320       // OpenMP context selectors.
6321       Diag(E->getExprLoc(),
6322            diag::err_omp_declare_variant_user_condition_not_constant)
6323           << E;
6324     }
6325     return true;
6326   };
6327   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6328     return None;
6329 
6330   // Convert VariantRef expression to the type of the original function to
6331   // resolve possible conflicts.
6332   ExprResult VariantRefCast = VariantRef;
6333   if (LangOpts.CPlusPlus) {
6334     QualType FnPtrType;
6335     auto *Method = dyn_cast<CXXMethodDecl>(FD);
6336     if (Method && !Method->isStatic()) {
6337       const Type *ClassType =
6338           Context.getTypeDeclType(Method->getParent()).getTypePtr();
6339       FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6340       ExprResult ER;
6341       {
6342         // Build adrr_of unary op to correctly handle type checks for member
6343         // functions.
6344         Sema::TentativeAnalysisScope Trap(*this);
6345         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6346                                   VariantRef);
6347       }
6348       if (!ER.isUsable()) {
6349         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6350             << VariantId << VariantRef->getSourceRange();
6351         return None;
6352       }
6353       VariantRef = ER.get();
6354     } else {
6355       FnPtrType = Context.getPointerType(FD->getType());
6356     }
6357     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6358     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6359       ImplicitConversionSequence ICS = TryImplicitConversion(
6360           VariantRef, FnPtrType.getUnqualifiedType(),
6361           /*SuppressUserConversions=*/false, AllowedExplicit::None,
6362           /*InOverloadResolution=*/false,
6363           /*CStyle=*/false,
6364           /*AllowObjCWritebackConversion=*/false);
6365       if (ICS.isFailure()) {
6366         Diag(VariantRef->getExprLoc(),
6367              diag::err_omp_declare_variant_incompat_types)
6368             << VariantRef->getType()
6369             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6370             << VariantRef->getSourceRange();
6371         return None;
6372       }
6373       VariantRefCast = PerformImplicitConversion(
6374           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6375       if (!VariantRefCast.isUsable())
6376         return None;
6377     }
6378     // Drop previously built artificial addr_of unary op for member functions.
6379     if (Method && !Method->isStatic()) {
6380       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6381       if (auto *UO = dyn_cast<UnaryOperator>(
6382               PossibleAddrOfVariantRef->IgnoreImplicit()))
6383         VariantRefCast = UO->getSubExpr();
6384     }
6385   }
6386 
6387   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6388   if (!ER.isUsable() ||
6389       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6390     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6391         << VariantId << VariantRef->getSourceRange();
6392     return None;
6393   }
6394 
6395   // The VariantRef must point to function.
6396   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6397   if (!DRE) {
6398     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6399         << VariantId << VariantRef->getSourceRange();
6400     return None;
6401   }
6402   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6403   if (!NewFD) {
6404     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6405         << VariantId << VariantRef->getSourceRange();
6406     return None;
6407   }
6408 
6409   // Check if function types are compatible in C.
6410   if (!LangOpts.CPlusPlus) {
6411     QualType NewType =
6412         Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6413     if (NewType.isNull()) {
6414       Diag(VariantRef->getExprLoc(),
6415            diag::err_omp_declare_variant_incompat_types)
6416           << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6417       return None;
6418     }
6419     if (NewType->isFunctionProtoType()) {
6420       if (FD->getType()->isFunctionNoProtoType())
6421         setPrototype(*this, FD, NewFD, NewType);
6422       else if (NewFD->getType()->isFunctionNoProtoType())
6423         setPrototype(*this, NewFD, FD, NewType);
6424     }
6425   }
6426 
6427   // Check if variant function is not marked with declare variant directive.
6428   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6429     Diag(VariantRef->getExprLoc(),
6430          diag::warn_omp_declare_variant_marked_as_declare_variant)
6431         << VariantRef->getSourceRange();
6432     SourceRange SR =
6433         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6434     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6435     return None;
6436   }
6437 
6438   enum DoesntSupport {
6439     VirtFuncs = 1,
6440     Constructors = 3,
6441     Destructors = 4,
6442     DeletedFuncs = 5,
6443     DefaultedFuncs = 6,
6444     ConstexprFuncs = 7,
6445     ConstevalFuncs = 8,
6446   };
6447   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6448     if (CXXFD->isVirtual()) {
6449       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6450           << VirtFuncs;
6451       return None;
6452     }
6453 
6454     if (isa<CXXConstructorDecl>(FD)) {
6455       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6456           << Constructors;
6457       return None;
6458     }
6459 
6460     if (isa<CXXDestructorDecl>(FD)) {
6461       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6462           << Destructors;
6463       return None;
6464     }
6465   }
6466 
6467   if (FD->isDeleted()) {
6468     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6469         << DeletedFuncs;
6470     return None;
6471   }
6472 
6473   if (FD->isDefaulted()) {
6474     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6475         << DefaultedFuncs;
6476     return None;
6477   }
6478 
6479   if (FD->isConstexpr()) {
6480     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6481         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6482     return None;
6483   }
6484 
6485   // Check general compatibility.
6486   if (areMultiversionVariantFunctionsCompatible(
6487           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6488           PartialDiagnosticAt(SourceLocation(),
6489                               PartialDiagnostic::NullDiagnostic()),
6490           PartialDiagnosticAt(
6491               VariantRef->getExprLoc(),
6492               PDiag(diag::err_omp_declare_variant_doesnt_support)),
6493           PartialDiagnosticAt(VariantRef->getExprLoc(),
6494                               PDiag(diag::err_omp_declare_variant_diff)
6495                                   << FD->getLocation()),
6496           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6497           /*CLinkageMayDiffer=*/true))
6498     return None;
6499   return std::make_pair(FD, cast<Expr>(DRE));
6500 }
6501 
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6502 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6503                                               Expr *VariantRef,
6504                                               OMPTraitInfo &TI,
6505                                               SourceRange SR) {
6506   auto *NewAttr =
6507       OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6508   FD->addAttr(NewAttr);
6509 }
6510 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6511 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6512                                               Stmt *AStmt,
6513                                               SourceLocation StartLoc,
6514                                               SourceLocation EndLoc) {
6515   if (!AStmt)
6516     return StmtError();
6517 
6518   auto *CS = cast<CapturedStmt>(AStmt);
6519   // 1.2.2 OpenMP Language Terminology
6520   // Structured block - An executable statement with a single entry at the
6521   // top and a single exit at the bottom.
6522   // The point of exit cannot be a branch out of the structured block.
6523   // longjmp() and throw() must not violate the entry/exit criteria.
6524   CS->getCapturedDecl()->setNothrow();
6525 
6526   setFunctionHasBranchProtectedScope();
6527 
6528   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6529                                       DSAStack->getTaskgroupReductionRef(),
6530                                       DSAStack->isCancelRegion());
6531 }
6532 
6533 namespace {
6534 /// Iteration space of a single for loop.
6535 struct LoopIterationSpace final {
6536   /// True if the condition operator is the strict compare operator (<, > or
6537   /// !=).
6538   bool IsStrictCompare = false;
6539   /// Condition of the loop.
6540   Expr *PreCond = nullptr;
6541   /// This expression calculates the number of iterations in the loop.
6542   /// It is always possible to calculate it before starting the loop.
6543   Expr *NumIterations = nullptr;
6544   /// The loop counter variable.
6545   Expr *CounterVar = nullptr;
6546   /// Private loop counter variable.
6547   Expr *PrivateCounterVar = nullptr;
6548   /// This is initializer for the initial value of #CounterVar.
6549   Expr *CounterInit = nullptr;
6550   /// This is step for the #CounterVar used to generate its update:
6551   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6552   Expr *CounterStep = nullptr;
6553   /// Should step be subtracted?
6554   bool Subtract = false;
6555   /// Source range of the loop init.
6556   SourceRange InitSrcRange;
6557   /// Source range of the loop condition.
6558   SourceRange CondSrcRange;
6559   /// Source range of the loop increment.
6560   SourceRange IncSrcRange;
6561   /// Minimum value that can have the loop control variable. Used to support
6562   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6563   /// since only such variables can be used in non-loop invariant expressions.
6564   Expr *MinValue = nullptr;
6565   /// Maximum value that can have the loop control variable. Used to support
6566   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6567   /// since only such variables can be used in non-loop invariant expressions.
6568   Expr *MaxValue = nullptr;
6569   /// true, if the lower bound depends on the outer loop control var.
6570   bool IsNonRectangularLB = false;
6571   /// true, if the upper bound depends on the outer loop control var.
6572   bool IsNonRectangularUB = false;
6573   /// Index of the loop this loop depends on and forms non-rectangular loop
6574   /// nest.
6575   unsigned LoopDependentIdx = 0;
6576   /// Final condition for the non-rectangular loop nest support. It is used to
6577   /// check that the number of iterations for this particular counter must be
6578   /// finished.
6579   Expr *FinalCondition = nullptr;
6580 };
6581 
6582 /// Helper class for checking canonical form of the OpenMP loops and
6583 /// extracting iteration space of each loop in the loop nest, that will be used
6584 /// for IR generation.
6585 class OpenMPIterationSpaceChecker {
6586   /// Reference to Sema.
6587   Sema &SemaRef;
6588   /// Data-sharing stack.
6589   DSAStackTy &Stack;
6590   /// A location for diagnostics (when there is no some better location).
6591   SourceLocation DefaultLoc;
6592   /// A location for diagnostics (when increment is not compatible).
6593   SourceLocation ConditionLoc;
6594   /// A source location for referring to loop init later.
6595   SourceRange InitSrcRange;
6596   /// A source location for referring to condition later.
6597   SourceRange ConditionSrcRange;
6598   /// A source location for referring to increment later.
6599   SourceRange IncrementSrcRange;
6600   /// Loop variable.
6601   ValueDecl *LCDecl = nullptr;
6602   /// Reference to loop variable.
6603   Expr *LCRef = nullptr;
6604   /// Lower bound (initializer for the var).
6605   Expr *LB = nullptr;
6606   /// Upper bound.
6607   Expr *UB = nullptr;
6608   /// Loop step (increment).
6609   Expr *Step = nullptr;
6610   /// This flag is true when condition is one of:
6611   ///   Var <  UB
6612   ///   Var <= UB
6613   ///   UB  >  Var
6614   ///   UB  >= Var
6615   /// This will have no value when the condition is !=
6616   llvm::Optional<bool> TestIsLessOp;
6617   /// This flag is true when condition is strict ( < or > ).
6618   bool TestIsStrictOp = false;
6619   /// This flag is true when step is subtracted on each iteration.
6620   bool SubtractStep = false;
6621   /// The outer loop counter this loop depends on (if any).
6622   const ValueDecl *DepDecl = nullptr;
6623   /// Contains number of loop (starts from 1) on which loop counter init
6624   /// expression of this loop depends on.
6625   Optional<unsigned> InitDependOnLC;
6626   /// Contains number of loop (starts from 1) on which loop counter condition
6627   /// expression of this loop depends on.
6628   Optional<unsigned> CondDependOnLC;
6629   /// Checks if the provide statement depends on the loop counter.
6630   Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6631   /// Original condition required for checking of the exit condition for
6632   /// non-rectangular loop.
6633   Expr *Condition = nullptr;
6634 
6635 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,DSAStackTy & Stack,SourceLocation DefaultLoc)6636   OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6637                               SourceLocation DefaultLoc)
6638       : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6639         ConditionLoc(DefaultLoc) {}
6640   /// Check init-expr for canonical loop form and save loop counter
6641   /// variable - #Var and its initialization value - #LB.
6642   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6643   /// Check test-expr for canonical form, save upper-bound (#UB), flags
6644   /// for less/greater and for strict/non-strict comparison.
6645   bool checkAndSetCond(Expr *S);
6646   /// Check incr-expr for canonical loop form and return true if it
6647   /// does not conform, otherwise save loop step (#Step).
6648   bool checkAndSetInc(Expr *S);
6649   /// Return the loop counter variable.
getLoopDecl() const6650   ValueDecl *getLoopDecl() const { return LCDecl; }
6651   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const6652   Expr *getLoopDeclRefExpr() const { return LCRef; }
6653   /// Source range of the loop init.
getInitSrcRange() const6654   SourceRange getInitSrcRange() const { return InitSrcRange; }
6655   /// Source range of the loop condition.
getConditionSrcRange() const6656   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6657   /// Source range of the loop increment.
getIncrementSrcRange() const6658   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6659   /// True if the step should be subtracted.
shouldSubtractStep() const6660   bool shouldSubtractStep() const { return SubtractStep; }
6661   /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const6662   bool isStrictTestOp() const { return TestIsStrictOp; }
6663   /// Build the expression to calculate the number of iterations.
6664   Expr *buildNumIterations(
6665       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6666       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6667   /// Build the precondition expression for the loops.
6668   Expr *
6669   buildPreCond(Scope *S, Expr *Cond,
6670                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6671   /// Build reference expression to the counter be used for codegen.
6672   DeclRefExpr *
6673   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6674                   DSAStackTy &DSA) const;
6675   /// Build reference expression to the private counter be used for
6676   /// codegen.
6677   Expr *buildPrivateCounterVar() const;
6678   /// Build initialization of the counter be used for codegen.
6679   Expr *buildCounterInit() const;
6680   /// Build step of the counter be used for codegen.
6681   Expr *buildCounterStep() const;
6682   /// Build loop data with counter value for depend clauses in ordered
6683   /// directives.
6684   Expr *
6685   buildOrderedLoopData(Scope *S, Expr *Counter,
6686                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6687                        SourceLocation Loc, Expr *Inc = nullptr,
6688                        OverloadedOperatorKind OOK = OO_Amp);
6689   /// Builds the minimum value for the loop counter.
6690   std::pair<Expr *, Expr *> buildMinMaxValues(
6691       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6692   /// Builds final condition for the non-rectangular loops.
6693   Expr *buildFinalCondition(Scope *S) const;
6694   /// Return true if any expression is dependent.
6695   bool dependent() const;
6696   /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const6697   bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6698   /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const6699   bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6700   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const6701   unsigned getLoopDependentIdx() const {
6702     return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6703   }
6704 
6705 private:
6706   /// Check the right-hand side of an assignment in the increment
6707   /// expression.
6708   bool checkAndSetIncRHS(Expr *RHS);
6709   /// Helper to set loop counter variable and its initializer.
6710   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6711                       bool EmitDiags);
6712   /// Helper to set upper bound.
6713   bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6714              SourceRange SR, SourceLocation SL);
6715   /// Helper to set loop increment.
6716   bool setStep(Expr *NewStep, bool Subtract);
6717 };
6718 
dependent() const6719 bool OpenMPIterationSpaceChecker::dependent() const {
6720   if (!LCDecl) {
6721     assert(!LB && !UB && !Step);
6722     return false;
6723   }
6724   return LCDecl->getType()->isDependentType() ||
6725          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6726          (Step && Step->isValueDependent());
6727 }
6728 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)6729 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6730                                                  Expr *NewLCRefExpr,
6731                                                  Expr *NewLB, bool EmitDiags) {
6732   // State consistency checking to ensure correct usage.
6733   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
6734          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6735   if (!NewLCDecl || !NewLB)
6736     return true;
6737   LCDecl = getCanonicalDecl(NewLCDecl);
6738   LCRef = NewLCRefExpr;
6739   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6740     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6741       if ((Ctor->isCopyOrMoveConstructor() ||
6742            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6743           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6744         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6745   LB = NewLB;
6746   if (EmitDiags)
6747     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6748   return false;
6749 }
6750 
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)6751 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6752                                         llvm::Optional<bool> LessOp,
6753                                         bool StrictOp, SourceRange SR,
6754                                         SourceLocation SL) {
6755   // State consistency checking to ensure correct usage.
6756   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
6757          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6758   if (!NewUB)
6759     return true;
6760   UB = NewUB;
6761   if (LessOp)
6762     TestIsLessOp = LessOp;
6763   TestIsStrictOp = StrictOp;
6764   ConditionSrcRange = SR;
6765   ConditionLoc = SL;
6766   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6767   return false;
6768 }
6769 
setStep(Expr * NewStep,bool Subtract)6770 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6771   // State consistency checking to ensure correct usage.
6772   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
6773   if (!NewStep)
6774     return true;
6775   if (!NewStep->isValueDependent()) {
6776     // Check that the step is integer expression.
6777     SourceLocation StepLoc = NewStep->getBeginLoc();
6778     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6779         StepLoc, getExprAsWritten(NewStep));
6780     if (Val.isInvalid())
6781       return true;
6782     NewStep = Val.get();
6783 
6784     // OpenMP [2.6, Canonical Loop Form, Restrictions]
6785     //  If test-expr is of form var relational-op b and relational-op is < or
6786     //  <= then incr-expr must cause var to increase on each iteration of the
6787     //  loop. If test-expr is of form var relational-op b and relational-op is
6788     //  > or >= then incr-expr must cause var to decrease on each iteration of
6789     //  the loop.
6790     //  If test-expr is of form b relational-op var and relational-op is < or
6791     //  <= then incr-expr must cause var to decrease on each iteration of the
6792     //  loop. If test-expr is of form b relational-op var and relational-op is
6793     //  > or >= then incr-expr must cause var to increase on each iteration of
6794     //  the loop.
6795     Optional<llvm::APSInt> Result =
6796         NewStep->getIntegerConstantExpr(SemaRef.Context);
6797     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6798     bool IsConstNeg =
6799         Result && Result->isSigned() && (Subtract != Result->isNegative());
6800     bool IsConstPos =
6801         Result && Result->isSigned() && (Subtract == Result->isNegative());
6802     bool IsConstZero = Result && !Result->getBoolValue();
6803 
6804     // != with increment is treated as <; != with decrement is treated as >
6805     if (!TestIsLessOp.hasValue())
6806       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6807     if (UB && (IsConstZero ||
6808                (TestIsLessOp.getValue() ?
6809                   (IsConstNeg || (IsUnsigned && Subtract)) :
6810                   (IsConstPos || (IsUnsigned && !Subtract))))) {
6811       SemaRef.Diag(NewStep->getExprLoc(),
6812                    diag::err_omp_loop_incr_not_compatible)
6813           << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6814       SemaRef.Diag(ConditionLoc,
6815                    diag::note_omp_loop_cond_requres_compatible_incr)
6816           << TestIsLessOp.getValue() << ConditionSrcRange;
6817       return true;
6818     }
6819     if (TestIsLessOp.getValue() == Subtract) {
6820       NewStep =
6821           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6822               .get();
6823       Subtract = !Subtract;
6824     }
6825   }
6826 
6827   Step = NewStep;
6828   SubtractStep = Subtract;
6829   return false;
6830 }
6831 
6832 namespace {
6833 /// Checker for the non-rectangular loops. Checks if the initializer or
6834 /// condition expression references loop counter variable.
6835 class LoopCounterRefChecker final
6836     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6837   Sema &SemaRef;
6838   DSAStackTy &Stack;
6839   const ValueDecl *CurLCDecl = nullptr;
6840   const ValueDecl *DepDecl = nullptr;
6841   const ValueDecl *PrevDepDecl = nullptr;
6842   bool IsInitializer = true;
6843   unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)6844   bool checkDecl(const Expr *E, const ValueDecl *VD) {
6845     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6846       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6847           << (IsInitializer ? 0 : 1);
6848       return false;
6849     }
6850     const auto &&Data = Stack.isLoopControlVariable(VD);
6851     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6852     // The type of the loop iterator on which we depend may not have a random
6853     // access iterator type.
6854     if (Data.first && VD->getType()->isRecordType()) {
6855       SmallString<128> Name;
6856       llvm::raw_svector_ostream OS(Name);
6857       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6858                                /*Qualified=*/true);
6859       SemaRef.Diag(E->getExprLoc(),
6860                    diag::err_omp_wrong_dependency_iterator_type)
6861           << OS.str();
6862       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6863       return false;
6864     }
6865     if (Data.first &&
6866         (DepDecl || (PrevDepDecl &&
6867                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6868       if (!DepDecl && PrevDepDecl)
6869         DepDecl = PrevDepDecl;
6870       SmallString<128> Name;
6871       llvm::raw_svector_ostream OS(Name);
6872       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6873                                     /*Qualified=*/true);
6874       SemaRef.Diag(E->getExprLoc(),
6875                    diag::err_omp_invariant_or_linear_dependency)
6876           << OS.str();
6877       return false;
6878     }
6879     if (Data.first) {
6880       DepDecl = VD;
6881       BaseLoopId = Data.first;
6882     }
6883     return Data.first;
6884   }
6885 
6886 public:
VisitDeclRefExpr(const DeclRefExpr * E)6887   bool VisitDeclRefExpr(const DeclRefExpr *E) {
6888     const ValueDecl *VD = E->getDecl();
6889     if (isa<VarDecl>(VD))
6890       return checkDecl(E, VD);
6891     return false;
6892   }
VisitMemberExpr(const MemberExpr * E)6893   bool VisitMemberExpr(const MemberExpr *E) {
6894     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6895       const ValueDecl *VD = E->getMemberDecl();
6896       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6897         return checkDecl(E, VD);
6898     }
6899     return false;
6900   }
VisitStmt(const Stmt * S)6901   bool VisitStmt(const Stmt *S) {
6902     bool Res = false;
6903     for (const Stmt *Child : S->children())
6904       Res = (Child && Visit(Child)) || Res;
6905     return Res;
6906   }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr)6907   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6908                                  const ValueDecl *CurLCDecl, bool IsInitializer,
6909                                  const ValueDecl *PrevDepDecl = nullptr)
6910       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6911         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
getBaseLoopId() const6912   unsigned getBaseLoopId() const {
6913     assert(CurLCDecl && "Expected loop dependency.");
6914     return BaseLoopId;
6915   }
getDepDecl() const6916   const ValueDecl *getDepDecl() const {
6917     assert(CurLCDecl && "Expected loop dependency.");
6918     return DepDecl;
6919   }
6920 };
6921 } // namespace
6922 
6923 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)6924 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6925                                                      bool IsInitializer) {
6926   // Check for the non-rectangular loops.
6927   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6928                                         DepDecl);
6929   if (LoopStmtChecker.Visit(S)) {
6930     DepDecl = LoopStmtChecker.getDepDecl();
6931     return LoopStmtChecker.getBaseLoopId();
6932   }
6933   return llvm::None;
6934 }
6935 
checkAndSetInit(Stmt * S,bool EmitDiags)6936 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6937   // Check init-expr for canonical loop form and save loop counter
6938   // variable - #Var and its initialization value - #LB.
6939   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6940   //   var = lb
6941   //   integer-type var = lb
6942   //   random-access-iterator-type var = lb
6943   //   pointer-type var = lb
6944   //
6945   if (!S) {
6946     if (EmitDiags) {
6947       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6948     }
6949     return true;
6950   }
6951   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6952     if (!ExprTemp->cleanupsHaveSideEffects())
6953       S = ExprTemp->getSubExpr();
6954 
6955   InitSrcRange = S->getSourceRange();
6956   if (Expr *E = dyn_cast<Expr>(S))
6957     S = E->IgnoreParens();
6958   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6959     if (BO->getOpcode() == BO_Assign) {
6960       Expr *LHS = BO->getLHS()->IgnoreParens();
6961       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6962         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6963           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6964             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6965                                   EmitDiags);
6966         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6967       }
6968       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6969         if (ME->isArrow() &&
6970             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6971           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6972                                 EmitDiags);
6973       }
6974     }
6975   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6976     if (DS->isSingleDecl()) {
6977       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6978         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6979           // Accept non-canonical init form here but emit ext. warning.
6980           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6981             SemaRef.Diag(S->getBeginLoc(),
6982                          diag::ext_omp_loop_not_canonical_init)
6983                 << S->getSourceRange();
6984           return setLCDeclAndLB(
6985               Var,
6986               buildDeclRefExpr(SemaRef, Var,
6987                                Var->getType().getNonReferenceType(),
6988                                DS->getBeginLoc()),
6989               Var->getInit(), EmitDiags);
6990         }
6991       }
6992     }
6993   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6994     if (CE->getOperator() == OO_Equal) {
6995       Expr *LHS = CE->getArg(0);
6996       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6997         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6998           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6999             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7000                                   EmitDiags);
7001         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7002       }
7003       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7004         if (ME->isArrow() &&
7005             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7006           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7007                                 EmitDiags);
7008       }
7009     }
7010   }
7011 
7012   if (dependent() || SemaRef.CurContext->isDependentContext())
7013     return false;
7014   if (EmitDiags) {
7015     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7016         << S->getSourceRange();
7017   }
7018   return true;
7019 }
7020 
7021 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7022 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)7023 static const ValueDecl *getInitLCDecl(const Expr *E) {
7024   if (!E)
7025     return nullptr;
7026   E = getExprAsWritten(E);
7027   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7028     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7029       if ((Ctor->isCopyOrMoveConstructor() ||
7030            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7031           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7032         E = CE->getArg(0)->IgnoreParenImpCasts();
7033   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7034     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7035       return getCanonicalDecl(VD);
7036   }
7037   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7038     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7039       return getCanonicalDecl(ME->getMemberDecl());
7040   return nullptr;
7041 }
7042 
checkAndSetCond(Expr * S)7043 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7044   // Check test-expr for canonical form, save upper-bound UB, flags for
7045   // less/greater and for strict/non-strict comparison.
7046   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7047   //   var relational-op b
7048   //   b relational-op var
7049   //
7050   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7051   if (!S) {
7052     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7053         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7054     return true;
7055   }
7056   Condition = S;
7057   S = getExprAsWritten(S);
7058   SourceLocation CondLoc = S->getBeginLoc();
7059   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7060     if (BO->isRelationalOp()) {
7061       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7062         return setUB(BO->getRHS(),
7063                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7064                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7065                      BO->getSourceRange(), BO->getOperatorLoc());
7066       if (getInitLCDecl(BO->getRHS()) == LCDecl)
7067         return setUB(BO->getLHS(),
7068                      (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7069                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7070                      BO->getSourceRange(), BO->getOperatorLoc());
7071     } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7072       return setUB(
7073           getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7074           /*LessOp=*/llvm::None,
7075           /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7076   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7077     if (CE->getNumArgs() == 2) {
7078       auto Op = CE->getOperator();
7079       switch (Op) {
7080       case OO_Greater:
7081       case OO_GreaterEqual:
7082       case OO_Less:
7083       case OO_LessEqual:
7084         if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7085           return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7086                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7087                        CE->getOperatorLoc());
7088         if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7089           return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7090                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7091                        CE->getOperatorLoc());
7092         break;
7093       case OO_ExclaimEqual:
7094         if (IneqCondIsCanonical)
7095           return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7096                                                               : CE->getArg(0),
7097                        /*LessOp=*/llvm::None,
7098                        /*StrictOp=*/true, CE->getSourceRange(),
7099                        CE->getOperatorLoc());
7100         break;
7101       default:
7102         break;
7103       }
7104     }
7105   }
7106   if (dependent() || SemaRef.CurContext->isDependentContext())
7107     return false;
7108   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7109       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7110   return true;
7111 }
7112 
checkAndSetIncRHS(Expr * RHS)7113 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7114   // RHS of canonical loop form increment can be:
7115   //   var + incr
7116   //   incr + var
7117   //   var - incr
7118   //
7119   RHS = RHS->IgnoreParenImpCasts();
7120   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7121     if (BO->isAdditiveOp()) {
7122       bool IsAdd = BO->getOpcode() == BO_Add;
7123       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7124         return setStep(BO->getRHS(), !IsAdd);
7125       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7126         return setStep(BO->getLHS(), /*Subtract=*/false);
7127     }
7128   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7129     bool IsAdd = CE->getOperator() == OO_Plus;
7130     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7131       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7132         return setStep(CE->getArg(1), !IsAdd);
7133       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7134         return setStep(CE->getArg(0), /*Subtract=*/false);
7135     }
7136   }
7137   if (dependent() || SemaRef.CurContext->isDependentContext())
7138     return false;
7139   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7140       << RHS->getSourceRange() << LCDecl;
7141   return true;
7142 }
7143 
checkAndSetInc(Expr * S)7144 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7145   // Check incr-expr for canonical loop form and return true if it
7146   // does not conform.
7147   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7148   //   ++var
7149   //   var++
7150   //   --var
7151   //   var--
7152   //   var += incr
7153   //   var -= incr
7154   //   var = var + incr
7155   //   var = incr + var
7156   //   var = var - incr
7157   //
7158   if (!S) {
7159     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7160     return true;
7161   }
7162   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7163     if (!ExprTemp->cleanupsHaveSideEffects())
7164       S = ExprTemp->getSubExpr();
7165 
7166   IncrementSrcRange = S->getSourceRange();
7167   S = S->IgnoreParens();
7168   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7169     if (UO->isIncrementDecrementOp() &&
7170         getInitLCDecl(UO->getSubExpr()) == LCDecl)
7171       return setStep(SemaRef
7172                          .ActOnIntegerConstant(UO->getBeginLoc(),
7173                                                (UO->isDecrementOp() ? -1 : 1))
7174                          .get(),
7175                      /*Subtract=*/false);
7176   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7177     switch (BO->getOpcode()) {
7178     case BO_AddAssign:
7179     case BO_SubAssign:
7180       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7181         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7182       break;
7183     case BO_Assign:
7184       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7185         return checkAndSetIncRHS(BO->getRHS());
7186       break;
7187     default:
7188       break;
7189     }
7190   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7191     switch (CE->getOperator()) {
7192     case OO_PlusPlus:
7193     case OO_MinusMinus:
7194       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7195         return setStep(SemaRef
7196                            .ActOnIntegerConstant(
7197                                CE->getBeginLoc(),
7198                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7199                            .get(),
7200                        /*Subtract=*/false);
7201       break;
7202     case OO_PlusEqual:
7203     case OO_MinusEqual:
7204       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7205         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7206       break;
7207     case OO_Equal:
7208       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7209         return checkAndSetIncRHS(CE->getArg(1));
7210       break;
7211     default:
7212       break;
7213     }
7214   }
7215   if (dependent() || SemaRef.CurContext->isDependentContext())
7216     return false;
7217   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7218       << S->getSourceRange() << LCDecl;
7219   return true;
7220 }
7221 
7222 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7223 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7224                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7225   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7226     return Capture;
7227   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7228     return SemaRef.PerformImplicitConversion(
7229         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7230         /*AllowExplicit=*/true);
7231   auto I = Captures.find(Capture);
7232   if (I != Captures.end())
7233     return buildCapture(SemaRef, Capture, I->second);
7234   DeclRefExpr *Ref = nullptr;
7235   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7236   Captures[Capture] = Ref;
7237   return Res;
7238 }
7239 
7240 /// Calculate number of iterations, transforming to unsigned, if number of
7241 /// iterations may be larger than the original type.
7242 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)7243 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7244                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7245                   bool TestIsStrictOp, bool RoundToStep,
7246                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7247   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7248   if (!NewStep.isUsable())
7249     return nullptr;
7250   llvm::APSInt LRes, SRes;
7251   bool IsLowerConst = false, IsStepConst = false;
7252   if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7253     LRes = *Res;
7254     IsLowerConst = true;
7255   }
7256   if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7257     SRes = *Res;
7258     IsStepConst = true;
7259   }
7260   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7261                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
7262                           (TestIsStrictOp && LRes.isStrictlyPositive()));
7263   bool NeedToReorganize = false;
7264   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7265   if (!NoNeedToConvert && IsLowerConst &&
7266       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7267     NoNeedToConvert = true;
7268     if (RoundToStep) {
7269       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7270                         ? LRes.getBitWidth()
7271                         : SRes.getBitWidth();
7272       LRes = LRes.extend(BW + 1);
7273       LRes.setIsSigned(true);
7274       SRes = SRes.extend(BW + 1);
7275       SRes.setIsSigned(true);
7276       LRes -= SRes;
7277       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7278       LRes = LRes.trunc(BW);
7279     }
7280     if (TestIsStrictOp) {
7281       unsigned BW = LRes.getBitWidth();
7282       LRes = LRes.extend(BW + 1);
7283       LRes.setIsSigned(true);
7284       ++LRes;
7285       NoNeedToConvert =
7286           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7287       // truncate to the original bitwidth.
7288       LRes = LRes.trunc(BW);
7289     }
7290     NeedToReorganize = NoNeedToConvert;
7291   }
7292   llvm::APSInt URes;
7293   bool IsUpperConst = false;
7294   if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7295     URes = *Res;
7296     IsUpperConst = true;
7297   }
7298   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7299       (!RoundToStep || IsStepConst)) {
7300     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7301                                                           : URes.getBitWidth();
7302     LRes = LRes.extend(BW + 1);
7303     LRes.setIsSigned(true);
7304     URes = URes.extend(BW + 1);
7305     URes.setIsSigned(true);
7306     URes -= LRes;
7307     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7308     NeedToReorganize = NoNeedToConvert;
7309   }
7310   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7311   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7312   // unsigned.
7313   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7314       !LCTy->isDependentType() && LCTy->isIntegerType()) {
7315     QualType LowerTy = Lower->getType();
7316     QualType UpperTy = Upper->getType();
7317     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7318     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7319     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7320         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7321       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7322           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7323       Upper =
7324           SemaRef
7325               .PerformImplicitConversion(
7326                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7327                   CastType, Sema::AA_Converting)
7328               .get();
7329       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7330       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7331     }
7332   }
7333   if (!Lower || !Upper || NewStep.isInvalid())
7334     return nullptr;
7335 
7336   ExprResult Diff;
7337   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7338   // 1]).
7339   if (NeedToReorganize) {
7340     Diff = Lower;
7341 
7342     if (RoundToStep) {
7343       // Lower - Step
7344       Diff =
7345           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7346       if (!Diff.isUsable())
7347         return nullptr;
7348     }
7349 
7350     // Lower - Step [+ 1]
7351     if (TestIsStrictOp)
7352       Diff = SemaRef.BuildBinOp(
7353           S, DefaultLoc, BO_Add, Diff.get(),
7354           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7355     if (!Diff.isUsable())
7356       return nullptr;
7357 
7358     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7359     if (!Diff.isUsable())
7360       return nullptr;
7361 
7362     // Upper - (Lower - Step [+ 1]).
7363     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7364     if (!Diff.isUsable())
7365       return nullptr;
7366   } else {
7367     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7368 
7369     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7370       // BuildBinOp already emitted error, this one is to point user to upper
7371       // and lower bound, and to tell what is passed to 'operator-'.
7372       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7373           << Upper->getSourceRange() << Lower->getSourceRange();
7374       return nullptr;
7375     }
7376 
7377     if (!Diff.isUsable())
7378       return nullptr;
7379 
7380     // Upper - Lower [- 1]
7381     if (TestIsStrictOp)
7382       Diff = SemaRef.BuildBinOp(
7383           S, DefaultLoc, BO_Sub, Diff.get(),
7384           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7385     if (!Diff.isUsable())
7386       return nullptr;
7387 
7388     if (RoundToStep) {
7389       // Upper - Lower [- 1] + Step
7390       Diff =
7391           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7392       if (!Diff.isUsable())
7393         return nullptr;
7394     }
7395   }
7396 
7397   // Parentheses (for dumping/debugging purposes only).
7398   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7399   if (!Diff.isUsable())
7400     return nullptr;
7401 
7402   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7403   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7404   if (!Diff.isUsable())
7405     return nullptr;
7406 
7407   return Diff.get();
7408 }
7409 
7410 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7411 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7412     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7413     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7414   QualType VarType = LCDecl->getType().getNonReferenceType();
7415   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7416       !SemaRef.getLangOpts().CPlusPlus)
7417     return nullptr;
7418   Expr *LBVal = LB;
7419   Expr *UBVal = UB;
7420   // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7421   // max(LB(MinVal), LB(MaxVal))
7422   if (InitDependOnLC) {
7423     const LoopIterationSpace &IS =
7424         ResultIterSpaces[ResultIterSpaces.size() - 1 -
7425                          InitDependOnLC.getValueOr(
7426                              CondDependOnLC.getValueOr(0))];
7427     if (!IS.MinValue || !IS.MaxValue)
7428       return nullptr;
7429     // OuterVar = Min
7430     ExprResult MinValue =
7431         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7432     if (!MinValue.isUsable())
7433       return nullptr;
7434 
7435     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7436                                              IS.CounterVar, MinValue.get());
7437     if (!LBMinVal.isUsable())
7438       return nullptr;
7439     // OuterVar = Min, LBVal
7440     LBMinVal =
7441         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7442     if (!LBMinVal.isUsable())
7443       return nullptr;
7444     // (OuterVar = Min, LBVal)
7445     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7446     if (!LBMinVal.isUsable())
7447       return nullptr;
7448 
7449     // OuterVar = Max
7450     ExprResult MaxValue =
7451         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7452     if (!MaxValue.isUsable())
7453       return nullptr;
7454 
7455     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7456                                              IS.CounterVar, MaxValue.get());
7457     if (!LBMaxVal.isUsable())
7458       return nullptr;
7459     // OuterVar = Max, LBVal
7460     LBMaxVal =
7461         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7462     if (!LBMaxVal.isUsable())
7463       return nullptr;
7464     // (OuterVar = Max, LBVal)
7465     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7466     if (!LBMaxVal.isUsable())
7467       return nullptr;
7468 
7469     Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7470     Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7471     if (!LBMin || !LBMax)
7472       return nullptr;
7473     // LB(MinVal) < LB(MaxVal)
7474     ExprResult MinLessMaxRes =
7475         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7476     if (!MinLessMaxRes.isUsable())
7477       return nullptr;
7478     Expr *MinLessMax =
7479         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7480     if (!MinLessMax)
7481       return nullptr;
7482     if (TestIsLessOp.getValue()) {
7483       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7484       // LB(MaxVal))
7485       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7486                                                     MinLessMax, LBMin, LBMax);
7487       if (!MinLB.isUsable())
7488         return nullptr;
7489       LBVal = MinLB.get();
7490     } else {
7491       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7492       // LB(MaxVal))
7493       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7494                                                     MinLessMax, LBMax, LBMin);
7495       if (!MaxLB.isUsable())
7496         return nullptr;
7497       LBVal = MaxLB.get();
7498     }
7499   }
7500   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7501   // min(UB(MinVal), UB(MaxVal))
7502   if (CondDependOnLC) {
7503     const LoopIterationSpace &IS =
7504         ResultIterSpaces[ResultIterSpaces.size() - 1 -
7505                          InitDependOnLC.getValueOr(
7506                              CondDependOnLC.getValueOr(0))];
7507     if (!IS.MinValue || !IS.MaxValue)
7508       return nullptr;
7509     // OuterVar = Min
7510     ExprResult MinValue =
7511         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7512     if (!MinValue.isUsable())
7513       return nullptr;
7514 
7515     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7516                                              IS.CounterVar, MinValue.get());
7517     if (!UBMinVal.isUsable())
7518       return nullptr;
7519     // OuterVar = Min, UBVal
7520     UBMinVal =
7521         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7522     if (!UBMinVal.isUsable())
7523       return nullptr;
7524     // (OuterVar = Min, UBVal)
7525     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7526     if (!UBMinVal.isUsable())
7527       return nullptr;
7528 
7529     // OuterVar = Max
7530     ExprResult MaxValue =
7531         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7532     if (!MaxValue.isUsable())
7533       return nullptr;
7534 
7535     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7536                                              IS.CounterVar, MaxValue.get());
7537     if (!UBMaxVal.isUsable())
7538       return nullptr;
7539     // OuterVar = Max, UBVal
7540     UBMaxVal =
7541         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7542     if (!UBMaxVal.isUsable())
7543       return nullptr;
7544     // (OuterVar = Max, UBVal)
7545     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7546     if (!UBMaxVal.isUsable())
7547       return nullptr;
7548 
7549     Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7550     Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7551     if (!UBMin || !UBMax)
7552       return nullptr;
7553     // UB(MinVal) > UB(MaxVal)
7554     ExprResult MinGreaterMaxRes =
7555         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7556     if (!MinGreaterMaxRes.isUsable())
7557       return nullptr;
7558     Expr *MinGreaterMax =
7559         tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7560     if (!MinGreaterMax)
7561       return nullptr;
7562     if (TestIsLessOp.getValue()) {
7563       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7564       // UB(MaxVal))
7565       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7566           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7567       if (!MaxUB.isUsable())
7568         return nullptr;
7569       UBVal = MaxUB.get();
7570     } else {
7571       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7572       // UB(MaxVal))
7573       ExprResult MinUB = SemaRef.ActOnConditionalOp(
7574           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7575       if (!MinUB.isUsable())
7576         return nullptr;
7577       UBVal = MinUB.get();
7578     }
7579   }
7580   Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7581   Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7582   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7583   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7584   if (!Upper || !Lower)
7585     return nullptr;
7586 
7587   ExprResult Diff =
7588       calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7589                         TestIsStrictOp, /*RoundToStep=*/true, Captures);
7590   if (!Diff.isUsable())
7591     return nullptr;
7592 
7593   // OpenMP runtime requires 32-bit or 64-bit loop variables.
7594   QualType Type = Diff.get()->getType();
7595   ASTContext &C = SemaRef.Context;
7596   bool UseVarType = VarType->hasIntegerRepresentation() &&
7597                     C.getTypeSize(Type) > C.getTypeSize(VarType);
7598   if (!Type->isIntegerType() || UseVarType) {
7599     unsigned NewSize =
7600         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7601     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7602                                : Type->hasSignedIntegerRepresentation();
7603     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7604     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7605       Diff = SemaRef.PerformImplicitConversion(
7606           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7607       if (!Diff.isUsable())
7608         return nullptr;
7609     }
7610   }
7611   if (LimitedType) {
7612     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7613     if (NewSize != C.getTypeSize(Type)) {
7614       if (NewSize < C.getTypeSize(Type)) {
7615         assert(NewSize == 64 && "incorrect loop var size");
7616         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7617             << InitSrcRange << ConditionSrcRange;
7618       }
7619       QualType NewType = C.getIntTypeForBitwidth(
7620           NewSize, Type->hasSignedIntegerRepresentation() ||
7621                        C.getTypeSize(Type) < NewSize);
7622       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7623         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7624                                                  Sema::AA_Converting, true);
7625         if (!Diff.isUsable())
7626           return nullptr;
7627       }
7628     }
7629   }
7630 
7631   return Diff.get();
7632 }
7633 
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7634 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7635     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7636   // Do not build for iterators, they cannot be used in non-rectangular loop
7637   // nests.
7638   if (LCDecl->getType()->isRecordType())
7639     return std::make_pair(nullptr, nullptr);
7640   // If we subtract, the min is in the condition, otherwise the min is in the
7641   // init value.
7642   Expr *MinExpr = nullptr;
7643   Expr *MaxExpr = nullptr;
7644   Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7645   Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7646   bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7647                                            : CondDependOnLC.hasValue();
7648   bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7649                                            : InitDependOnLC.hasValue();
7650   Expr *Lower =
7651       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7652   Expr *Upper =
7653       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7654   if (!Upper || !Lower)
7655     return std::make_pair(nullptr, nullptr);
7656 
7657   if (TestIsLessOp.getValue())
7658     MinExpr = Lower;
7659   else
7660     MaxExpr = Upper;
7661 
7662   // Build minimum/maximum value based on number of iterations.
7663   QualType VarType = LCDecl->getType().getNonReferenceType();
7664 
7665   ExprResult Diff =
7666       calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7667                         TestIsStrictOp, /*RoundToStep=*/false, Captures);
7668   if (!Diff.isUsable())
7669     return std::make_pair(nullptr, nullptr);
7670 
7671   // ((Upper - Lower [- 1]) / Step) * Step
7672   // Parentheses (for dumping/debugging purposes only).
7673   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7674   if (!Diff.isUsable())
7675     return std::make_pair(nullptr, nullptr);
7676 
7677   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7678   if (!NewStep.isUsable())
7679     return std::make_pair(nullptr, nullptr);
7680   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7681   if (!Diff.isUsable())
7682     return std::make_pair(nullptr, nullptr);
7683 
7684   // Parentheses (for dumping/debugging purposes only).
7685   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7686   if (!Diff.isUsable())
7687     return std::make_pair(nullptr, nullptr);
7688 
7689   // Convert to the ptrdiff_t, if original type is pointer.
7690   if (VarType->isAnyPointerType() &&
7691       !SemaRef.Context.hasSameType(
7692           Diff.get()->getType(),
7693           SemaRef.Context.getUnsignedPointerDiffType())) {
7694     Diff = SemaRef.PerformImplicitConversion(
7695         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7696         Sema::AA_Converting, /*AllowExplicit=*/true);
7697   }
7698   if (!Diff.isUsable())
7699     return std::make_pair(nullptr, nullptr);
7700 
7701   if (TestIsLessOp.getValue()) {
7702     // MinExpr = Lower;
7703     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7704     Diff = SemaRef.BuildBinOp(
7705         S, DefaultLoc, BO_Add,
7706         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7707         Diff.get());
7708     if (!Diff.isUsable())
7709       return std::make_pair(nullptr, nullptr);
7710   } else {
7711     // MaxExpr = Upper;
7712     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7713     Diff = SemaRef.BuildBinOp(
7714         S, DefaultLoc, BO_Sub,
7715         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7716         Diff.get());
7717     if (!Diff.isUsable())
7718       return std::make_pair(nullptr, nullptr);
7719   }
7720 
7721   // Convert to the original type.
7722   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7723     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7724                                              Sema::AA_Converting,
7725                                              /*AllowExplicit=*/true);
7726   if (!Diff.isUsable())
7727     return std::make_pair(nullptr, nullptr);
7728 
7729   Sema::TentativeAnalysisScope Trap(SemaRef);
7730   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7731   if (!Diff.isUsable())
7732     return std::make_pair(nullptr, nullptr);
7733 
7734   if (TestIsLessOp.getValue())
7735     MaxExpr = Diff.get();
7736   else
7737     MinExpr = Diff.get();
7738 
7739   return std::make_pair(MinExpr, MaxExpr);
7740 }
7741 
buildFinalCondition(Scope * S) const7742 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7743   if (InitDependOnLC || CondDependOnLC)
7744     return Condition;
7745   return nullptr;
7746 }
7747 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7748 Expr *OpenMPIterationSpaceChecker::buildPreCond(
7749     Scope *S, Expr *Cond,
7750     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7751   // Do not build a precondition when the condition/initialization is dependent
7752   // to prevent pessimistic early loop exit.
7753   // TODO: this can be improved by calculating min/max values but not sure that
7754   // it will be very effective.
7755   if (CondDependOnLC || InitDependOnLC)
7756     return SemaRef.PerformImplicitConversion(
7757         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7758         SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7759         /*AllowExplicit=*/true).get();
7760 
7761   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7762   Sema::TentativeAnalysisScope Trap(SemaRef);
7763 
7764   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7765   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7766   if (!NewLB.isUsable() || !NewUB.isUsable())
7767     return nullptr;
7768 
7769   ExprResult CondExpr =
7770       SemaRef.BuildBinOp(S, DefaultLoc,
7771                          TestIsLessOp.getValue() ?
7772                            (TestIsStrictOp ? BO_LT : BO_LE) :
7773                            (TestIsStrictOp ? BO_GT : BO_GE),
7774                          NewLB.get(), NewUB.get());
7775   if (CondExpr.isUsable()) {
7776     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7777                                                 SemaRef.Context.BoolTy))
7778       CondExpr = SemaRef.PerformImplicitConversion(
7779           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7780           /*AllowExplicit=*/true);
7781   }
7782 
7783   // Otherwise use original loop condition and evaluate it in runtime.
7784   return CondExpr.isUsable() ? CondExpr.get() : Cond;
7785 }
7786 
7787 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const7788 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7789     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7790     DSAStackTy &DSA) const {
7791   auto *VD = dyn_cast<VarDecl>(LCDecl);
7792   if (!VD) {
7793     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7794     DeclRefExpr *Ref = buildDeclRefExpr(
7795         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7796     const DSAStackTy::DSAVarData Data =
7797         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7798     // If the loop control decl is explicitly marked as private, do not mark it
7799     // as captured again.
7800     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7801       Captures.insert(std::make_pair(LCRef, Ref));
7802     return Ref;
7803   }
7804   return cast<DeclRefExpr>(LCRef);
7805 }
7806 
buildPrivateCounterVar() const7807 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7808   if (LCDecl && !LCDecl->isInvalidDecl()) {
7809     QualType Type = LCDecl->getType().getNonReferenceType();
7810     VarDecl *PrivateVar = buildVarDecl(
7811         SemaRef, DefaultLoc, Type, LCDecl->getName(),
7812         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7813         isa<VarDecl>(LCDecl)
7814             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7815             : nullptr);
7816     if (PrivateVar->isInvalidDecl())
7817       return nullptr;
7818     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7819   }
7820   return nullptr;
7821 }
7822 
7823 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const7824 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7825 
7826 /// Build step of the counter be used for codegen.
buildCounterStep() const7827 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7828 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)7829 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7830     Scope *S, Expr *Counter,
7831     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7832     Expr *Inc, OverloadedOperatorKind OOK) {
7833   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7834   if (!Cnt)
7835     return nullptr;
7836   if (Inc) {
7837     assert((OOK == OO_Plus || OOK == OO_Minus) &&
7838            "Expected only + or - operations for depend clauses.");
7839     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7840     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7841     if (!Cnt)
7842       return nullptr;
7843   }
7844   QualType VarType = LCDecl->getType().getNonReferenceType();
7845   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7846       !SemaRef.getLangOpts().CPlusPlus)
7847     return nullptr;
7848   // Upper - Lower
7849   Expr *Upper = TestIsLessOp.getValue()
7850                     ? Cnt
7851                     : tryBuildCapture(SemaRef, LB, Captures).get();
7852   Expr *Lower = TestIsLessOp.getValue()
7853                     ? tryBuildCapture(SemaRef, LB, Captures).get()
7854                     : Cnt;
7855   if (!Upper || !Lower)
7856     return nullptr;
7857 
7858   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7859                                       Step, VarType, /*TestIsStrictOp=*/false,
7860                                       /*RoundToStep=*/false, Captures);
7861   if (!Diff.isUsable())
7862     return nullptr;
7863 
7864   return Diff.get();
7865 }
7866 } // namespace
7867 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)7868 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7869   assert(getLangOpts().OpenMP && "OpenMP is not active.");
7870   assert(Init && "Expected loop in canonical form.");
7871   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
7872   if (AssociatedLoops > 0 &&
7873       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
7874     DSAStack->loopStart();
7875     OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
7876     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7877       if (ValueDecl *D = ISC.getLoopDecl()) {
7878         auto *VD = dyn_cast<VarDecl>(D);
7879         DeclRefExpr *PrivateRef = nullptr;
7880         if (!VD) {
7881           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7882             VD = Private;
7883           } else {
7884             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7885                                       /*WithInit=*/false);
7886             VD = cast<VarDecl>(PrivateRef->getDecl());
7887           }
7888         }
7889         DSAStack->addLoopControlVariable(D, VD);
7890         const Decl *LD = DSAStack->getPossiblyLoopCunter();
7891         if (LD != D->getCanonicalDecl()) {
7892           DSAStack->resetPossibleLoopCounter();
7893           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7894             MarkDeclarationsReferencedInExpr(
7895                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7896                                  Var->getType().getNonLValueExprType(Context),
7897                                  ForLoc, /*RefersToCapture=*/true));
7898         }
7899         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
7900         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7901         // Referenced in a Construct, C/C++]. The loop iteration variable in the
7902         // associated for-loop of a simd construct with just one associated
7903         // for-loop may be listed in a linear clause with a constant-linear-step
7904         // that is the increment of the associated for-loop. The loop iteration
7905         // variable(s) in the associated for-loop(s) of a for or parallel for
7906         // construct may be listed in a private or lastprivate clause.
7907         DSAStackTy::DSAVarData DVar =
7908             DSAStack->getTopDSA(D, /*FromParent=*/false);
7909         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7910         // is declared in the loop and it is predetermined as a private.
7911         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7912         OpenMPClauseKind PredeterminedCKind =
7913             isOpenMPSimdDirective(DKind)
7914                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7915                 : OMPC_private;
7916         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7917               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7918               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7919                                          DVar.CKind != OMPC_private))) ||
7920              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7921                DKind == OMPD_master_taskloop ||
7922                DKind == OMPD_parallel_master_taskloop ||
7923                isOpenMPDistributeDirective(DKind)) &&
7924               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7925               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7926             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7927           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7928               << getOpenMPClauseName(DVar.CKind)
7929               << getOpenMPDirectiveName(DKind)
7930               << getOpenMPClauseName(PredeterminedCKind);
7931           if (DVar.RefExpr == nullptr)
7932             DVar.CKind = PredeterminedCKind;
7933           reportOriginalDsa(*this, DSAStack, D, DVar,
7934                             /*IsLoopIterVar=*/true);
7935         } else if (LoopDeclRefExpr) {
7936           // Make the loop iteration variable private (for worksharing
7937           // constructs), linear (for simd directives with the only one
7938           // associated loop) or lastprivate (for simd directives with several
7939           // collapsed or ordered loops).
7940           if (DVar.CKind == OMPC_unknown)
7941             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7942                              PrivateRef);
7943         }
7944       }
7945     }
7946     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
7947   }
7948 }
7949 
7950 /// Called on a for stmt to check and extract its iteration space
7951 /// 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)7952 static bool checkOpenMPIterationSpace(
7953     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7954     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7955     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7956     Expr *OrderedLoopCountExpr,
7957     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7958     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7959     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7960   // OpenMP [2.9.1, Canonical Loop Form]
7961   //   for (init-expr; test-expr; incr-expr) structured-block
7962   //   for (range-decl: range-expr) structured-block
7963   auto *For = dyn_cast_or_null<ForStmt>(S);
7964   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7965   // Ranged for is supported only in OpenMP 5.0.
7966   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7967     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7968         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7969         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7970         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7971     if (TotalNestedLoopCount > 1) {
7972       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7973         SemaRef.Diag(DSA.getConstructLoc(),
7974                      diag::note_omp_collapse_ordered_expr)
7975             << 2 << CollapseLoopCountExpr->getSourceRange()
7976             << OrderedLoopCountExpr->getSourceRange();
7977       else if (CollapseLoopCountExpr)
7978         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7979                      diag::note_omp_collapse_ordered_expr)
7980             << 0 << CollapseLoopCountExpr->getSourceRange();
7981       else
7982         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7983                      diag::note_omp_collapse_ordered_expr)
7984             << 1 << OrderedLoopCountExpr->getSourceRange();
7985     }
7986     return true;
7987   }
7988   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
7989          "No loop body.");
7990 
7991   OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7992                                   For ? For->getForLoc() : CXXFor->getForLoc());
7993 
7994   // Check init.
7995   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7996   if (ISC.checkAndSetInit(Init))
7997     return true;
7998 
7999   bool HasErrors = false;
8000 
8001   // Check loop variable's type.
8002   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8003     // OpenMP [2.6, Canonical Loop Form]
8004     // Var is one of the following:
8005     //   A variable of signed or unsigned integer type.
8006     //   For C++, a variable of a random access iterator type.
8007     //   For C, a variable of a pointer type.
8008     QualType VarType = LCDecl->getType().getNonReferenceType();
8009     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8010         !VarType->isPointerType() &&
8011         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8012       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8013           << SemaRef.getLangOpts().CPlusPlus;
8014       HasErrors = true;
8015     }
8016 
8017     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8018     // a Construct
8019     // The loop iteration variable(s) in the associated for-loop(s) of a for or
8020     // parallel for construct is (are) private.
8021     // The loop iteration variable in the associated for-loop of a simd
8022     // construct with just one associated for-loop is linear with a
8023     // constant-linear-step that is the increment of the associated for-loop.
8024     // Exclude loop var from the list of variables with implicitly defined data
8025     // sharing attributes.
8026     VarsWithImplicitDSA.erase(LCDecl);
8027 
8028     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8029 
8030     // Check test-expr.
8031     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8032 
8033     // Check incr-expr.
8034     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8035   }
8036 
8037   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8038     return HasErrors;
8039 
8040   // Build the loop's iteration space representation.
8041   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8042       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8043   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8044       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8045                              (isOpenMPWorksharingDirective(DKind) ||
8046                               isOpenMPTaskLoopDirective(DKind) ||
8047                               isOpenMPDistributeDirective(DKind)),
8048                              Captures);
8049   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8050       ISC.buildCounterVar(Captures, DSA);
8051   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8052       ISC.buildPrivateCounterVar();
8053   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8054   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8055   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8056   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8057       ISC.getConditionSrcRange();
8058   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8059       ISC.getIncrementSrcRange();
8060   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8061   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8062       ISC.isStrictTestOp();
8063   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8064            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8065       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8066   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8067       ISC.buildFinalCondition(DSA.getCurScope());
8068   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8069       ISC.doesInitDependOnLC();
8070   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8071       ISC.doesCondDependOnLC();
8072   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8073       ISC.getLoopDependentIdx();
8074 
8075   HasErrors |=
8076       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8077        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8078        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8079        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8080        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8081        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8082   if (!HasErrors && DSA.isOrderedRegion()) {
8083     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8084       if (CurrentNestedLoopCount <
8085           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8086         DSA.getOrderedRegionParam().second->setLoopNumIterations(
8087             CurrentNestedLoopCount,
8088             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8089         DSA.getOrderedRegionParam().second->setLoopCounter(
8090             CurrentNestedLoopCount,
8091             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8092       }
8093     }
8094     for (auto &Pair : DSA.getDoacrossDependClauses()) {
8095       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8096         // Erroneous case - clause has some problems.
8097         continue;
8098       }
8099       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8100           Pair.second.size() <= CurrentNestedLoopCount) {
8101         // Erroneous case - clause has some problems.
8102         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8103         continue;
8104       }
8105       Expr *CntValue;
8106       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8107         CntValue = ISC.buildOrderedLoopData(
8108             DSA.getCurScope(),
8109             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8110             Pair.first->getDependencyLoc());
8111       else
8112         CntValue = ISC.buildOrderedLoopData(
8113             DSA.getCurScope(),
8114             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8115             Pair.first->getDependencyLoc(),
8116             Pair.second[CurrentNestedLoopCount].first,
8117             Pair.second[CurrentNestedLoopCount].second);
8118       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8119     }
8120   }
8121 
8122   return HasErrors;
8123 }
8124 
8125 /// Build 'VarRef = Start.
8126 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8127 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8128                  ExprResult Start, bool IsNonRectangularLB,
8129                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8130   // Build 'VarRef = Start.
8131   ExprResult NewStart = IsNonRectangularLB
8132                             ? Start.get()
8133                             : tryBuildCapture(SemaRef, Start.get(), Captures);
8134   if (!NewStart.isUsable())
8135     return ExprError();
8136   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8137                                    VarRef.get()->getType())) {
8138     NewStart = SemaRef.PerformImplicitConversion(
8139         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8140         /*AllowExplicit=*/true);
8141     if (!NewStart.isUsable())
8142       return ExprError();
8143   }
8144 
8145   ExprResult Init =
8146       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8147   return Init;
8148 }
8149 
8150 /// 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)8151 static ExprResult buildCounterUpdate(
8152     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8153     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8154     bool IsNonRectangularLB,
8155     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8156   // Add parentheses (for debugging purposes only).
8157   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8158   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8159       !Step.isUsable())
8160     return ExprError();
8161 
8162   ExprResult NewStep = Step;
8163   if (Captures)
8164     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8165   if (NewStep.isInvalid())
8166     return ExprError();
8167   ExprResult Update =
8168       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8169   if (!Update.isUsable())
8170     return ExprError();
8171 
8172   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8173   // 'VarRef = Start (+|-) Iter * Step'.
8174   if (!Start.isUsable())
8175     return ExprError();
8176   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8177   if (!NewStart.isUsable())
8178     return ExprError();
8179   if (Captures && !IsNonRectangularLB)
8180     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8181   if (NewStart.isInvalid())
8182     return ExprError();
8183 
8184   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8185   ExprResult SavedUpdate = Update;
8186   ExprResult UpdateVal;
8187   if (VarRef.get()->getType()->isOverloadableType() ||
8188       NewStart.get()->getType()->isOverloadableType() ||
8189       Update.get()->getType()->isOverloadableType()) {
8190     Sema::TentativeAnalysisScope Trap(SemaRef);
8191 
8192     Update =
8193         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8194     if (Update.isUsable()) {
8195       UpdateVal =
8196           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8197                              VarRef.get(), SavedUpdate.get());
8198       if (UpdateVal.isUsable()) {
8199         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8200                                             UpdateVal.get());
8201       }
8202     }
8203   }
8204 
8205   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8206   if (!Update.isUsable() || !UpdateVal.isUsable()) {
8207     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8208                                 NewStart.get(), SavedUpdate.get());
8209     if (!Update.isUsable())
8210       return ExprError();
8211 
8212     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8213                                      VarRef.get()->getType())) {
8214       Update = SemaRef.PerformImplicitConversion(
8215           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8216       if (!Update.isUsable())
8217         return ExprError();
8218     }
8219 
8220     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8221   }
8222   return Update;
8223 }
8224 
8225 /// Convert integer expression \a E to make it have at least \a Bits
8226 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8227 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8228   if (E == nullptr)
8229     return ExprError();
8230   ASTContext &C = SemaRef.Context;
8231   QualType OldType = E->getType();
8232   unsigned HasBits = C.getTypeSize(OldType);
8233   if (HasBits >= Bits)
8234     return ExprResult(E);
8235   // OK to convert to signed, because new type has more bits than old.
8236   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8237   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8238                                            true);
8239 }
8240 
8241 /// Check if the given expression \a E is a constant integer that fits
8242 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8243 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8244   if (E == nullptr)
8245     return false;
8246   if (Optional<llvm::APSInt> Result =
8247           E->getIntegerConstantExpr(SemaRef.Context))
8248     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8249   return false;
8250 }
8251 
8252 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8253 static Stmt *buildPreInits(ASTContext &Context,
8254                            MutableArrayRef<Decl *> PreInits) {
8255   if (!PreInits.empty()) {
8256     return new (Context) DeclStmt(
8257         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8258         SourceLocation(), SourceLocation());
8259   }
8260   return nullptr;
8261 }
8262 
8263 /// Build preinits statement for the given declarations.
8264 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8265 buildPreInits(ASTContext &Context,
8266               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8267   if (!Captures.empty()) {
8268     SmallVector<Decl *, 16> PreInits;
8269     for (const auto &Pair : Captures)
8270       PreInits.push_back(Pair.second->getDecl());
8271     return buildPreInits(Context, PreInits);
8272   }
8273   return nullptr;
8274 }
8275 
8276 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8277 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8278   Expr *PostUpdate = nullptr;
8279   if (!PostUpdates.empty()) {
8280     for (Expr *E : PostUpdates) {
8281       Expr *ConvE = S.BuildCStyleCastExpr(
8282                          E->getExprLoc(),
8283                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8284                          E->getExprLoc(), E)
8285                         .get();
8286       PostUpdate = PostUpdate
8287                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8288                                               PostUpdate, ConvE)
8289                              .get()
8290                        : ConvE;
8291     }
8292   }
8293   return PostUpdate;
8294 }
8295 
8296 /// Called on a for stmt to check itself and nested loops (if any).
8297 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8298 /// number of collapsed loops otherwise.
8299 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopDirective::HelperExprs & Built)8300 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8301                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8302                 DSAStackTy &DSA,
8303                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8304                 OMPLoopDirective::HelperExprs &Built) {
8305   unsigned NestedLoopCount = 1;
8306   if (CollapseLoopCountExpr) {
8307     // Found 'collapse' clause - calculate collapse number.
8308     Expr::EvalResult Result;
8309     if (!CollapseLoopCountExpr->isValueDependent() &&
8310         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8311       NestedLoopCount = Result.Val.getInt().getLimitedValue();
8312     } else {
8313       Built.clear(/*Size=*/1);
8314       return 1;
8315     }
8316   }
8317   unsigned OrderedLoopCount = 1;
8318   if (OrderedLoopCountExpr) {
8319     // Found 'ordered' clause - calculate collapse number.
8320     Expr::EvalResult EVResult;
8321     if (!OrderedLoopCountExpr->isValueDependent() &&
8322         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8323                                             SemaRef.getASTContext())) {
8324       llvm::APSInt Result = EVResult.Val.getInt();
8325       if (Result.getLimitedValue() < NestedLoopCount) {
8326         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8327                      diag::err_omp_wrong_ordered_loop_count)
8328             << OrderedLoopCountExpr->getSourceRange();
8329         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8330                      diag::note_collapse_loop_count)
8331             << CollapseLoopCountExpr->getSourceRange();
8332       }
8333       OrderedLoopCount = Result.getLimitedValue();
8334     } else {
8335       Built.clear(/*Size=*/1);
8336       return 1;
8337     }
8338   }
8339   // This is helper routine for loop directives (e.g., 'for', 'simd',
8340   // 'for simd', etc.).
8341   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8342   SmallVector<LoopIterationSpace, 4> IterSpaces(
8343       std::max(OrderedLoopCount, NestedLoopCount));
8344   Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8345   for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8346     if (checkOpenMPIterationSpace(
8347             DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8348             std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8349             OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8350       return 0;
8351     // Move on to the next nested for loop, or to the loop body.
8352     // OpenMP [2.8.1, simd construct, Restrictions]
8353     // All loops associated with the construct must be perfectly nested; that
8354     // is, there must be no intervening code nor any OpenMP directive between
8355     // any two loops.
8356     if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8357       CurStmt = For->getBody();
8358     } else {
8359       assert(isa<CXXForRangeStmt>(CurStmt) &&
8360              "Expected canonical for or range-based for loops.");
8361       CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8362     }
8363     CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8364         CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8365   }
8366   for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8367     if (checkOpenMPIterationSpace(
8368             DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8369             std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8370             OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8371       return 0;
8372     if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8373       // Handle initialization of captured loop iterator variables.
8374       auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8375       if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8376         Captures[DRE] = DRE;
8377       }
8378     }
8379     // Move on to the next nested for loop, or to the loop body.
8380     // OpenMP [2.8.1, simd construct, Restrictions]
8381     // All loops associated with the construct must be perfectly nested; that
8382     // is, there must be no intervening code nor any OpenMP directive between
8383     // any two loops.
8384     if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8385       CurStmt = For->getBody();
8386     } else {
8387       assert(isa<CXXForRangeStmt>(CurStmt) &&
8388              "Expected canonical for or range-based for loops.");
8389       CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8390     }
8391     CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8392         CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8393   }
8394 
8395   Built.clear(/* size */ NestedLoopCount);
8396 
8397   if (SemaRef.CurContext->isDependentContext())
8398     return NestedLoopCount;
8399 
8400   // An example of what is generated for the following code:
8401   //
8402   //   #pragma omp simd collapse(2) ordered(2)
8403   //   for (i = 0; i < NI; ++i)
8404   //     for (k = 0; k < NK; ++k)
8405   //       for (j = J0; j < NJ; j+=2) {
8406   //         <loop body>
8407   //       }
8408   //
8409   // We generate the code below.
8410   // Note: the loop body may be outlined in CodeGen.
8411   // Note: some counters may be C++ classes, operator- is used to find number of
8412   // iterations and operator+= to calculate counter value.
8413   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8414   // or i64 is currently supported).
8415   //
8416   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8417   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8418   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8419   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8420   //     // similar updates for vars in clauses (e.g. 'linear')
8421   //     <loop body (using local i and j)>
8422   //   }
8423   //   i = NI; // assign final values of counters
8424   //   j = NJ;
8425   //
8426 
8427   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8428   // the iteration counts of the collapsed for loops.
8429   // Precondition tests if there is at least one iteration (all conditions are
8430   // true).
8431   auto PreCond = ExprResult(IterSpaces[0].PreCond);
8432   Expr *N0 = IterSpaces[0].NumIterations;
8433   ExprResult LastIteration32 =
8434       widenIterationCount(/*Bits=*/32,
8435                           SemaRef
8436                               .PerformImplicitConversion(
8437                                   N0->IgnoreImpCasts(), N0->getType(),
8438                                   Sema::AA_Converting, /*AllowExplicit=*/true)
8439                               .get(),
8440                           SemaRef);
8441   ExprResult LastIteration64 = widenIterationCount(
8442       /*Bits=*/64,
8443       SemaRef
8444           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8445                                      Sema::AA_Converting,
8446                                      /*AllowExplicit=*/true)
8447           .get(),
8448       SemaRef);
8449 
8450   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8451     return NestedLoopCount;
8452 
8453   ASTContext &C = SemaRef.Context;
8454   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8455 
8456   Scope *CurScope = DSA.getCurScope();
8457   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8458     if (PreCond.isUsable()) {
8459       PreCond =
8460           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8461                              PreCond.get(), IterSpaces[Cnt].PreCond);
8462     }
8463     Expr *N = IterSpaces[Cnt].NumIterations;
8464     SourceLocation Loc = N->getExprLoc();
8465     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8466     if (LastIteration32.isUsable())
8467       LastIteration32 = SemaRef.BuildBinOp(
8468           CurScope, Loc, BO_Mul, LastIteration32.get(),
8469           SemaRef
8470               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8471                                          Sema::AA_Converting,
8472                                          /*AllowExplicit=*/true)
8473               .get());
8474     if (LastIteration64.isUsable())
8475       LastIteration64 = SemaRef.BuildBinOp(
8476           CurScope, Loc, BO_Mul, LastIteration64.get(),
8477           SemaRef
8478               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8479                                          Sema::AA_Converting,
8480                                          /*AllowExplicit=*/true)
8481               .get());
8482   }
8483 
8484   // Choose either the 32-bit or 64-bit version.
8485   ExprResult LastIteration = LastIteration64;
8486   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8487       (LastIteration32.isUsable() &&
8488        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8489        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8490         fitsInto(
8491             /*Bits=*/32,
8492             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8493             LastIteration64.get(), SemaRef))))
8494     LastIteration = LastIteration32;
8495   QualType VType = LastIteration.get()->getType();
8496   QualType RealVType = VType;
8497   QualType StrideVType = VType;
8498   if (isOpenMPTaskLoopDirective(DKind)) {
8499     VType =
8500         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8501     StrideVType =
8502         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8503   }
8504 
8505   if (!LastIteration.isUsable())
8506     return 0;
8507 
8508   // Save the number of iterations.
8509   ExprResult NumIterations = LastIteration;
8510   {
8511     LastIteration = SemaRef.BuildBinOp(
8512         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8513         LastIteration.get(),
8514         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8515     if (!LastIteration.isUsable())
8516       return 0;
8517   }
8518 
8519   // Calculate the last iteration number beforehand instead of doing this on
8520   // each iteration. Do not do this if the number of iterations may be kfold-ed.
8521   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8522   ExprResult CalcLastIteration;
8523   if (!IsConstant) {
8524     ExprResult SaveRef =
8525         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8526     LastIteration = SaveRef;
8527 
8528     // Prepare SaveRef + 1.
8529     NumIterations = SemaRef.BuildBinOp(
8530         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8531         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8532     if (!NumIterations.isUsable())
8533       return 0;
8534   }
8535 
8536   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8537 
8538   // Build variables passed into runtime, necessary for worksharing directives.
8539   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8540   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8541       isOpenMPDistributeDirective(DKind)) {
8542     // Lower bound variable, initialized with zero.
8543     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8544     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8545     SemaRef.AddInitializerToDecl(LBDecl,
8546                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8547                                  /*DirectInit*/ false);
8548 
8549     // Upper bound variable, initialized with last iteration number.
8550     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8551     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8552     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8553                                  /*DirectInit*/ false);
8554 
8555     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8556     // This will be used to implement clause 'lastprivate'.
8557     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8558     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8559     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8560     SemaRef.AddInitializerToDecl(ILDecl,
8561                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8562                                  /*DirectInit*/ false);
8563 
8564     // Stride variable returned by runtime (we initialize it to 1 by default).
8565     VarDecl *STDecl =
8566         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8567     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8568     SemaRef.AddInitializerToDecl(STDecl,
8569                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8570                                  /*DirectInit*/ false);
8571 
8572     // Build expression: UB = min(UB, LastIteration)
8573     // It is necessary for CodeGen of directives with static scheduling.
8574     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8575                                                 UB.get(), LastIteration.get());
8576     ExprResult CondOp = SemaRef.ActOnConditionalOp(
8577         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8578         LastIteration.get(), UB.get());
8579     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8580                              CondOp.get());
8581     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8582 
8583     // If we have a combined directive that combines 'distribute', 'for' or
8584     // 'simd' we need to be able to access the bounds of the schedule of the
8585     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8586     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8587     if (isOpenMPLoopBoundSharingDirective(DKind)) {
8588       // Lower bound variable, initialized with zero.
8589       VarDecl *CombLBDecl =
8590           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8591       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8592       SemaRef.AddInitializerToDecl(
8593           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8594           /*DirectInit*/ false);
8595 
8596       // Upper bound variable, initialized with last iteration number.
8597       VarDecl *CombUBDecl =
8598           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8599       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8600       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8601                                    /*DirectInit*/ false);
8602 
8603       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8604           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8605       ExprResult CombCondOp =
8606           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8607                                      LastIteration.get(), CombUB.get());
8608       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8609                                    CombCondOp.get());
8610       CombEUB =
8611           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8612 
8613       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8614       // We expect to have at least 2 more parameters than the 'parallel'
8615       // directive does - the lower and upper bounds of the previous schedule.
8616       assert(CD->getNumParams() >= 4 &&
8617              "Unexpected number of parameters in loop combined directive");
8618 
8619       // Set the proper type for the bounds given what we learned from the
8620       // enclosed loops.
8621       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8622       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8623 
8624       // Previous lower and upper bounds are obtained from the region
8625       // parameters.
8626       PrevLB =
8627           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8628       PrevUB =
8629           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8630     }
8631   }
8632 
8633   // Build the iteration variable and its initialization before loop.
8634   ExprResult IV;
8635   ExprResult Init, CombInit;
8636   {
8637     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8638     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8639     Expr *RHS =
8640         (isOpenMPWorksharingDirective(DKind) ||
8641          isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8642             ? LB.get()
8643             : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8644     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8645     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8646 
8647     if (isOpenMPLoopBoundSharingDirective(DKind)) {
8648       Expr *CombRHS =
8649           (isOpenMPWorksharingDirective(DKind) ||
8650            isOpenMPTaskLoopDirective(DKind) ||
8651            isOpenMPDistributeDirective(DKind))
8652               ? CombLB.get()
8653               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8654       CombInit =
8655           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8656       CombInit =
8657           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8658     }
8659   }
8660 
8661   bool UseStrictCompare =
8662       RealVType->hasUnsignedIntegerRepresentation() &&
8663       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8664         return LIS.IsStrictCompare;
8665       });
8666   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8667   // unsigned IV)) for worksharing loops.
8668   SourceLocation CondLoc = AStmt->getBeginLoc();
8669   Expr *BoundUB = UB.get();
8670   if (UseStrictCompare) {
8671     BoundUB =
8672         SemaRef
8673             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8674                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8675             .get();
8676     BoundUB =
8677         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8678   }
8679   ExprResult Cond =
8680       (isOpenMPWorksharingDirective(DKind) ||
8681        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8682           ? SemaRef.BuildBinOp(CurScope, CondLoc,
8683                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8684                                BoundUB)
8685           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8686                                NumIterations.get());
8687   ExprResult CombDistCond;
8688   if (isOpenMPLoopBoundSharingDirective(DKind)) {
8689     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8690                                       NumIterations.get());
8691   }
8692 
8693   ExprResult CombCond;
8694   if (isOpenMPLoopBoundSharingDirective(DKind)) {
8695     Expr *BoundCombUB = CombUB.get();
8696     if (UseStrictCompare) {
8697       BoundCombUB =
8698           SemaRef
8699               .BuildBinOp(
8700                   CurScope, CondLoc, BO_Add, BoundCombUB,
8701                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8702               .get();
8703       BoundCombUB =
8704           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8705               .get();
8706     }
8707     CombCond =
8708         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8709                            IV.get(), BoundCombUB);
8710   }
8711   // Loop increment (IV = IV + 1)
8712   SourceLocation IncLoc = AStmt->getBeginLoc();
8713   ExprResult Inc =
8714       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8715                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8716   if (!Inc.isUsable())
8717     return 0;
8718   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8719   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8720   if (!Inc.isUsable())
8721     return 0;
8722 
8723   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8724   // Used for directives with static scheduling.
8725   // In combined construct, add combined version that use CombLB and CombUB
8726   // base variables for the update
8727   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8728   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8729       isOpenMPDistributeDirective(DKind)) {
8730     // LB + ST
8731     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8732     if (!NextLB.isUsable())
8733       return 0;
8734     // LB = LB + ST
8735     NextLB =
8736         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8737     NextLB =
8738         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8739     if (!NextLB.isUsable())
8740       return 0;
8741     // UB + ST
8742     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8743     if (!NextUB.isUsable())
8744       return 0;
8745     // UB = UB + ST
8746     NextUB =
8747         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8748     NextUB =
8749         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8750     if (!NextUB.isUsable())
8751       return 0;
8752     if (isOpenMPLoopBoundSharingDirective(DKind)) {
8753       CombNextLB =
8754           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8755       if (!NextLB.isUsable())
8756         return 0;
8757       // LB = LB + ST
8758       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8759                                       CombNextLB.get());
8760       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8761                                                /*DiscardedValue*/ false);
8762       if (!CombNextLB.isUsable())
8763         return 0;
8764       // UB + ST
8765       CombNextUB =
8766           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8767       if (!CombNextUB.isUsable())
8768         return 0;
8769       // UB = UB + ST
8770       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8771                                       CombNextUB.get());
8772       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8773                                                /*DiscardedValue*/ false);
8774       if (!CombNextUB.isUsable())
8775         return 0;
8776     }
8777   }
8778 
8779   // Create increment expression for distribute loop when combined in a same
8780   // directive with for as IV = IV + ST; ensure upper bound expression based
8781   // on PrevUB instead of NumIterations - used to implement 'for' when found
8782   // in combination with 'distribute', like in 'distribute parallel for'
8783   SourceLocation DistIncLoc = AStmt->getBeginLoc();
8784   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8785   if (isOpenMPLoopBoundSharingDirective(DKind)) {
8786     DistCond = SemaRef.BuildBinOp(
8787         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8788     assert(DistCond.isUsable() && "distribute cond expr was not built");
8789 
8790     DistInc =
8791         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8792     assert(DistInc.isUsable() && "distribute inc expr was not built");
8793     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8794                                  DistInc.get());
8795     DistInc =
8796         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8797     assert(DistInc.isUsable() && "distribute inc expr was not built");
8798 
8799     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8800     // construct
8801     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8802     ExprResult IsUBGreater =
8803         SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8804     ExprResult CondOp = SemaRef.ActOnConditionalOp(
8805         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8806     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8807                                  CondOp.get());
8808     PrevEUB =
8809         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8810 
8811     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8812     // parallel for is in combination with a distribute directive with
8813     // schedule(static, 1)
8814     Expr *BoundPrevUB = PrevUB.get();
8815     if (UseStrictCompare) {
8816       BoundPrevUB =
8817           SemaRef
8818               .BuildBinOp(
8819                   CurScope, CondLoc, BO_Add, BoundPrevUB,
8820                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8821               .get();
8822       BoundPrevUB =
8823           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8824               .get();
8825     }
8826     ParForInDistCond =
8827         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8828                            IV.get(), BoundPrevUB);
8829   }
8830 
8831   // Build updates and final values of the loop counters.
8832   bool HasErrors = false;
8833   Built.Counters.resize(NestedLoopCount);
8834   Built.Inits.resize(NestedLoopCount);
8835   Built.Updates.resize(NestedLoopCount);
8836   Built.Finals.resize(NestedLoopCount);
8837   Built.DependentCounters.resize(NestedLoopCount);
8838   Built.DependentInits.resize(NestedLoopCount);
8839   Built.FinalsConditions.resize(NestedLoopCount);
8840   {
8841     // We implement the following algorithm for obtaining the
8842     // original loop iteration variable values based on the
8843     // value of the collapsed loop iteration variable IV.
8844     //
8845     // Let n+1 be the number of collapsed loops in the nest.
8846     // Iteration variables (I0, I1, .... In)
8847     // Iteration counts (N0, N1, ... Nn)
8848     //
8849     // Acc = IV;
8850     //
8851     // To compute Ik for loop k, 0 <= k <= n, generate:
8852     //    Prod = N(k+1) * N(k+2) * ... * Nn;
8853     //    Ik = Acc / Prod;
8854     //    Acc -= Ik * Prod;
8855     //
8856     ExprResult Acc = IV;
8857     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8858       LoopIterationSpace &IS = IterSpaces[Cnt];
8859       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8860       ExprResult Iter;
8861 
8862       // Compute prod
8863       ExprResult Prod =
8864           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8865       for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8866         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8867                                   IterSpaces[K].NumIterations);
8868 
8869       // Iter = Acc / Prod
8870       // If there is at least one more inner loop to avoid
8871       // multiplication by 1.
8872       if (Cnt + 1 < NestedLoopCount)
8873         Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8874                                   Acc.get(), Prod.get());
8875       else
8876         Iter = Acc;
8877       if (!Iter.isUsable()) {
8878         HasErrors = true;
8879         break;
8880       }
8881 
8882       // Update Acc:
8883       // Acc -= Iter * Prod
8884       // Check if there is at least one more inner loop to avoid
8885       // multiplication by 1.
8886       if (Cnt + 1 < NestedLoopCount)
8887         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8888                                   Iter.get(), Prod.get());
8889       else
8890         Prod = Iter;
8891       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8892                                Acc.get(), Prod.get());
8893 
8894       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8895       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8896       DeclRefExpr *CounterVar = buildDeclRefExpr(
8897           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8898           /*RefersToCapture=*/true);
8899       ExprResult Init =
8900           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8901                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
8902       if (!Init.isUsable()) {
8903         HasErrors = true;
8904         break;
8905       }
8906       ExprResult Update = buildCounterUpdate(
8907           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8908           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8909       if (!Update.isUsable()) {
8910         HasErrors = true;
8911         break;
8912       }
8913 
8914       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8915       ExprResult Final =
8916           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8917                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
8918                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
8919       if (!Final.isUsable()) {
8920         HasErrors = true;
8921         break;
8922       }
8923 
8924       if (!Update.isUsable() || !Final.isUsable()) {
8925         HasErrors = true;
8926         break;
8927       }
8928       // Save results
8929       Built.Counters[Cnt] = IS.CounterVar;
8930       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8931       Built.Inits[Cnt] = Init.get();
8932       Built.Updates[Cnt] = Update.get();
8933       Built.Finals[Cnt] = Final.get();
8934       Built.DependentCounters[Cnt] = nullptr;
8935       Built.DependentInits[Cnt] = nullptr;
8936       Built.FinalsConditions[Cnt] = nullptr;
8937       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8938         Built.DependentCounters[Cnt] =
8939             Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8940         Built.DependentInits[Cnt] =
8941             Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8942         Built.FinalsConditions[Cnt] = IS.FinalCondition;
8943       }
8944     }
8945   }
8946 
8947   if (HasErrors)
8948     return 0;
8949 
8950   // Save results
8951   Built.IterationVarRef = IV.get();
8952   Built.LastIteration = LastIteration.get();
8953   Built.NumIterations = NumIterations.get();
8954   Built.CalcLastIteration = SemaRef
8955                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
8956                                                      /*DiscardedValue=*/false)
8957                                 .get();
8958   Built.PreCond = PreCond.get();
8959   Built.PreInits = buildPreInits(C, Captures);
8960   Built.Cond = Cond.get();
8961   Built.Init = Init.get();
8962   Built.Inc = Inc.get();
8963   Built.LB = LB.get();
8964   Built.UB = UB.get();
8965   Built.IL = IL.get();
8966   Built.ST = ST.get();
8967   Built.EUB = EUB.get();
8968   Built.NLB = NextLB.get();
8969   Built.NUB = NextUB.get();
8970   Built.PrevLB = PrevLB.get();
8971   Built.PrevUB = PrevUB.get();
8972   Built.DistInc = DistInc.get();
8973   Built.PrevEUB = PrevEUB.get();
8974   Built.DistCombinedFields.LB = CombLB.get();
8975   Built.DistCombinedFields.UB = CombUB.get();
8976   Built.DistCombinedFields.EUB = CombEUB.get();
8977   Built.DistCombinedFields.Init = CombInit.get();
8978   Built.DistCombinedFields.Cond = CombCond.get();
8979   Built.DistCombinedFields.NLB = CombNextLB.get();
8980   Built.DistCombinedFields.NUB = CombNextUB.get();
8981   Built.DistCombinedFields.DistCond = CombDistCond.get();
8982   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8983 
8984   return NestedLoopCount;
8985 }
8986 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)8987 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8988   auto CollapseClauses =
8989       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8990   if (CollapseClauses.begin() != CollapseClauses.end())
8991     return (*CollapseClauses.begin())->getNumForLoops();
8992   return nullptr;
8993 }
8994 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)8995 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8996   auto OrderedClauses =
8997       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8998   if (OrderedClauses.begin() != OrderedClauses.end())
8999     return (*OrderedClauses.begin())->getNumForLoops();
9000   return nullptr;
9001 }
9002 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)9003 static bool checkSimdlenSafelenSpecified(Sema &S,
9004                                          const ArrayRef<OMPClause *> Clauses) {
9005   const OMPSafelenClause *Safelen = nullptr;
9006   const OMPSimdlenClause *Simdlen = nullptr;
9007 
9008   for (const OMPClause *Clause : Clauses) {
9009     if (Clause->getClauseKind() == OMPC_safelen)
9010       Safelen = cast<OMPSafelenClause>(Clause);
9011     else if (Clause->getClauseKind() == OMPC_simdlen)
9012       Simdlen = cast<OMPSimdlenClause>(Clause);
9013     if (Safelen && Simdlen)
9014       break;
9015   }
9016 
9017   if (Simdlen && Safelen) {
9018     const Expr *SimdlenLength = Simdlen->getSimdlen();
9019     const Expr *SafelenLength = Safelen->getSafelen();
9020     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9021         SimdlenLength->isInstantiationDependent() ||
9022         SimdlenLength->containsUnexpandedParameterPack())
9023       return false;
9024     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9025         SafelenLength->isInstantiationDependent() ||
9026         SafelenLength->containsUnexpandedParameterPack())
9027       return false;
9028     Expr::EvalResult SimdlenResult, SafelenResult;
9029     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9030     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9031     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9032     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9033     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9034     // If both simdlen and safelen clauses are specified, the value of the
9035     // simdlen parameter must be less than or equal to the value of the safelen
9036     // parameter.
9037     if (SimdlenRes > SafelenRes) {
9038       S.Diag(SimdlenLength->getExprLoc(),
9039              diag::err_omp_wrong_simdlen_safelen_values)
9040           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9041       return true;
9042     }
9043   }
9044   return false;
9045 }
9046 
9047 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9048 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9049                                SourceLocation StartLoc, SourceLocation EndLoc,
9050                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9051   if (!AStmt)
9052     return StmtError();
9053 
9054   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9055   OMPLoopDirective::HelperExprs B;
9056   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9057   // define the nested loops number.
9058   unsigned NestedLoopCount = checkOpenMPLoop(
9059       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9060       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9061   if (NestedLoopCount == 0)
9062     return StmtError();
9063 
9064   assert((CurContext->isDependentContext() || B.builtAll()) &&
9065          "omp simd loop exprs were not built");
9066 
9067   if (!CurContext->isDependentContext()) {
9068     // Finalize the clauses that need pre-built expressions for CodeGen.
9069     for (OMPClause *C : Clauses) {
9070       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9071         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9072                                      B.NumIterations, *this, CurScope,
9073                                      DSAStack))
9074           return StmtError();
9075     }
9076   }
9077 
9078   if (checkSimdlenSafelenSpecified(*this, Clauses))
9079     return StmtError();
9080 
9081   setFunctionHasBranchProtectedScope();
9082   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9083                                   Clauses, AStmt, B);
9084 }
9085 
9086 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9087 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9088                               SourceLocation StartLoc, SourceLocation EndLoc,
9089                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9090   if (!AStmt)
9091     return StmtError();
9092 
9093   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9094   OMPLoopDirective::HelperExprs B;
9095   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9096   // define the nested loops number.
9097   unsigned NestedLoopCount = checkOpenMPLoop(
9098       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9099       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9100   if (NestedLoopCount == 0)
9101     return StmtError();
9102 
9103   assert((CurContext->isDependentContext() || B.builtAll()) &&
9104          "omp for loop exprs were not built");
9105 
9106   if (!CurContext->isDependentContext()) {
9107     // Finalize the clauses that need pre-built expressions for CodeGen.
9108     for (OMPClause *C : Clauses) {
9109       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9110         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9111                                      B.NumIterations, *this, CurScope,
9112                                      DSAStack))
9113           return StmtError();
9114     }
9115   }
9116 
9117   setFunctionHasBranchProtectedScope();
9118   return OMPForDirective::Create(
9119       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9120       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9121 }
9122 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9123 StmtResult Sema::ActOnOpenMPForSimdDirective(
9124     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9125     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9126   if (!AStmt)
9127     return StmtError();
9128 
9129   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9130   OMPLoopDirective::HelperExprs B;
9131   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9132   // define the nested loops number.
9133   unsigned NestedLoopCount =
9134       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9135                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9136                       VarsWithImplicitDSA, B);
9137   if (NestedLoopCount == 0)
9138     return StmtError();
9139 
9140   assert((CurContext->isDependentContext() || B.builtAll()) &&
9141          "omp for simd loop exprs were not built");
9142 
9143   if (!CurContext->isDependentContext()) {
9144     // Finalize the clauses that need pre-built expressions for CodeGen.
9145     for (OMPClause *C : Clauses) {
9146       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9147         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9148                                      B.NumIterations, *this, CurScope,
9149                                      DSAStack))
9150           return StmtError();
9151     }
9152   }
9153 
9154   if (checkSimdlenSafelenSpecified(*this, Clauses))
9155     return StmtError();
9156 
9157   setFunctionHasBranchProtectedScope();
9158   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9159                                      Clauses, AStmt, B);
9160 }
9161 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9162 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9163                                               Stmt *AStmt,
9164                                               SourceLocation StartLoc,
9165                                               SourceLocation EndLoc) {
9166   if (!AStmt)
9167     return StmtError();
9168 
9169   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9170   auto BaseStmt = AStmt;
9171   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9172     BaseStmt = CS->getCapturedStmt();
9173   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9174     auto S = C->children();
9175     if (S.begin() == S.end())
9176       return StmtError();
9177     // All associated statements must be '#pragma omp section' except for
9178     // the first one.
9179     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9180       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9181         if (SectionStmt)
9182           Diag(SectionStmt->getBeginLoc(),
9183                diag::err_omp_sections_substmt_not_section);
9184         return StmtError();
9185       }
9186       cast<OMPSectionDirective>(SectionStmt)
9187           ->setHasCancel(DSAStack->isCancelRegion());
9188     }
9189   } else {
9190     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9191     return StmtError();
9192   }
9193 
9194   setFunctionHasBranchProtectedScope();
9195 
9196   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9197                                       DSAStack->getTaskgroupReductionRef(),
9198                                       DSAStack->isCancelRegion());
9199 }
9200 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9201 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9202                                              SourceLocation StartLoc,
9203                                              SourceLocation EndLoc) {
9204   if (!AStmt)
9205     return StmtError();
9206 
9207   setFunctionHasBranchProtectedScope();
9208   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9209 
9210   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9211                                      DSAStack->isCancelRegion());
9212 }
9213 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9214 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9215                                             Stmt *AStmt,
9216                                             SourceLocation StartLoc,
9217                                             SourceLocation EndLoc) {
9218   if (!AStmt)
9219     return StmtError();
9220 
9221   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9222 
9223   setFunctionHasBranchProtectedScope();
9224 
9225   // OpenMP [2.7.3, single Construct, Restrictions]
9226   // The copyprivate clause must not be used with the nowait clause.
9227   const OMPClause *Nowait = nullptr;
9228   const OMPClause *Copyprivate = nullptr;
9229   for (const OMPClause *Clause : Clauses) {
9230     if (Clause->getClauseKind() == OMPC_nowait)
9231       Nowait = Clause;
9232     else if (Clause->getClauseKind() == OMPC_copyprivate)
9233       Copyprivate = Clause;
9234     if (Copyprivate && Nowait) {
9235       Diag(Copyprivate->getBeginLoc(),
9236            diag::err_omp_single_copyprivate_with_nowait);
9237       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9238       return StmtError();
9239     }
9240   }
9241 
9242   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9243 }
9244 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9245 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9246                                             SourceLocation StartLoc,
9247                                             SourceLocation EndLoc) {
9248   if (!AStmt)
9249     return StmtError();
9250 
9251   setFunctionHasBranchProtectedScope();
9252 
9253   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9254 }
9255 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9256 StmtResult Sema::ActOnOpenMPCriticalDirective(
9257     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9258     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9259   if (!AStmt)
9260     return StmtError();
9261 
9262   bool ErrorFound = false;
9263   llvm::APSInt Hint;
9264   SourceLocation HintLoc;
9265   bool DependentHint = false;
9266   for (const OMPClause *C : Clauses) {
9267     if (C->getClauseKind() == OMPC_hint) {
9268       if (!DirName.getName()) {
9269         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9270         ErrorFound = true;
9271       }
9272       Expr *E = cast<OMPHintClause>(C)->getHint();
9273       if (E->isTypeDependent() || E->isValueDependent() ||
9274           E->isInstantiationDependent()) {
9275         DependentHint = true;
9276       } else {
9277         Hint = E->EvaluateKnownConstInt(Context);
9278         HintLoc = C->getBeginLoc();
9279       }
9280     }
9281   }
9282   if (ErrorFound)
9283     return StmtError();
9284   const auto Pair = DSAStack->getCriticalWithHint(DirName);
9285   if (Pair.first && DirName.getName() && !DependentHint) {
9286     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9287       Diag(StartLoc, diag::err_omp_critical_with_hint);
9288       if (HintLoc.isValid())
9289         Diag(HintLoc, diag::note_omp_critical_hint_here)
9290             << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9291       else
9292         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9293       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9294         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9295             << 1
9296             << C->getHint()->EvaluateKnownConstInt(Context).toString(
9297                    /*Radix=*/10, /*Signed=*/false);
9298       } else {
9299         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9300       }
9301     }
9302   }
9303 
9304   setFunctionHasBranchProtectedScope();
9305 
9306   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9307                                            Clauses, AStmt);
9308   if (!Pair.first && DirName.getName() && !DependentHint)
9309     DSAStack->addCriticalWithHint(Dir, Hint);
9310   return Dir;
9311 }
9312 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9313 StmtResult Sema::ActOnOpenMPParallelForDirective(
9314     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9315     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9316   if (!AStmt)
9317     return StmtError();
9318 
9319   auto *CS = cast<CapturedStmt>(AStmt);
9320   // 1.2.2 OpenMP Language Terminology
9321   // Structured block - An executable statement with a single entry at the
9322   // top and a single exit at the bottom.
9323   // The point of exit cannot be a branch out of the structured block.
9324   // longjmp() and throw() must not violate the entry/exit criteria.
9325   CS->getCapturedDecl()->setNothrow();
9326 
9327   OMPLoopDirective::HelperExprs B;
9328   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9329   // define the nested loops number.
9330   unsigned NestedLoopCount =
9331       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9332                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9333                       VarsWithImplicitDSA, B);
9334   if (NestedLoopCount == 0)
9335     return StmtError();
9336 
9337   assert((CurContext->isDependentContext() || B.builtAll()) &&
9338          "omp parallel for loop exprs were not built");
9339 
9340   if (!CurContext->isDependentContext()) {
9341     // Finalize the clauses that need pre-built expressions for CodeGen.
9342     for (OMPClause *C : Clauses) {
9343       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9344         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9345                                      B.NumIterations, *this, CurScope,
9346                                      DSAStack))
9347           return StmtError();
9348     }
9349   }
9350 
9351   setFunctionHasBranchProtectedScope();
9352   return OMPParallelForDirective::Create(
9353       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9354       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9355 }
9356 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9357 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9358     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9359     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9360   if (!AStmt)
9361     return StmtError();
9362 
9363   auto *CS = cast<CapturedStmt>(AStmt);
9364   // 1.2.2 OpenMP Language Terminology
9365   // Structured block - An executable statement with a single entry at the
9366   // top and a single exit at the bottom.
9367   // The point of exit cannot be a branch out of the structured block.
9368   // longjmp() and throw() must not violate the entry/exit criteria.
9369   CS->getCapturedDecl()->setNothrow();
9370 
9371   OMPLoopDirective::HelperExprs B;
9372   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9373   // define the nested loops number.
9374   unsigned NestedLoopCount =
9375       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9376                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9377                       VarsWithImplicitDSA, B);
9378   if (NestedLoopCount == 0)
9379     return StmtError();
9380 
9381   if (!CurContext->isDependentContext()) {
9382     // Finalize the clauses that need pre-built expressions for CodeGen.
9383     for (OMPClause *C : Clauses) {
9384       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9385         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9386                                      B.NumIterations, *this, CurScope,
9387                                      DSAStack))
9388           return StmtError();
9389     }
9390   }
9391 
9392   if (checkSimdlenSafelenSpecified(*this, Clauses))
9393     return StmtError();
9394 
9395   setFunctionHasBranchProtectedScope();
9396   return OMPParallelForSimdDirective::Create(
9397       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9398 }
9399 
9400 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9401 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9402                                          Stmt *AStmt, SourceLocation StartLoc,
9403                                          SourceLocation EndLoc) {
9404   if (!AStmt)
9405     return StmtError();
9406 
9407   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9408   auto *CS = cast<CapturedStmt>(AStmt);
9409   // 1.2.2 OpenMP Language Terminology
9410   // Structured block - An executable statement with a single entry at the
9411   // top and a single exit at the bottom.
9412   // The point of exit cannot be a branch out of the structured block.
9413   // longjmp() and throw() must not violate the entry/exit criteria.
9414   CS->getCapturedDecl()->setNothrow();
9415 
9416   setFunctionHasBranchProtectedScope();
9417 
9418   return OMPParallelMasterDirective::Create(
9419       Context, StartLoc, EndLoc, Clauses, AStmt,
9420       DSAStack->getTaskgroupReductionRef());
9421 }
9422 
9423 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9424 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9425                                            Stmt *AStmt, SourceLocation StartLoc,
9426                                            SourceLocation EndLoc) {
9427   if (!AStmt)
9428     return StmtError();
9429 
9430   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9431   auto BaseStmt = AStmt;
9432   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9433     BaseStmt = CS->getCapturedStmt();
9434   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9435     auto S = C->children();
9436     if (S.begin() == S.end())
9437       return StmtError();
9438     // All associated statements must be '#pragma omp section' except for
9439     // the first one.
9440     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9441       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9442         if (SectionStmt)
9443           Diag(SectionStmt->getBeginLoc(),
9444                diag::err_omp_parallel_sections_substmt_not_section);
9445         return StmtError();
9446       }
9447       cast<OMPSectionDirective>(SectionStmt)
9448           ->setHasCancel(DSAStack->isCancelRegion());
9449     }
9450   } else {
9451     Diag(AStmt->getBeginLoc(),
9452          diag::err_omp_parallel_sections_not_compound_stmt);
9453     return StmtError();
9454   }
9455 
9456   setFunctionHasBranchProtectedScope();
9457 
9458   return OMPParallelSectionsDirective::Create(
9459       Context, StartLoc, EndLoc, Clauses, AStmt,
9460       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9461 }
9462 
9463 /// detach and mergeable clauses are mutially exclusive, check for it.
checkDetachMergeableClauses(Sema & S,ArrayRef<OMPClause * > Clauses)9464 static bool checkDetachMergeableClauses(Sema &S,
9465                                         ArrayRef<OMPClause *> Clauses) {
9466   const OMPClause *PrevClause = nullptr;
9467   bool ErrorFound = false;
9468   for (const OMPClause *C : Clauses) {
9469     if (C->getClauseKind() == OMPC_detach ||
9470         C->getClauseKind() == OMPC_mergeable) {
9471       if (!PrevClause) {
9472         PrevClause = C;
9473       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9474         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9475             << getOpenMPClauseName(C->getClauseKind())
9476             << getOpenMPClauseName(PrevClause->getClauseKind());
9477         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9478             << getOpenMPClauseName(PrevClause->getClauseKind());
9479         ErrorFound = true;
9480       }
9481     }
9482   }
9483   return ErrorFound;
9484 }
9485 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9486 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9487                                           Stmt *AStmt, SourceLocation StartLoc,
9488                                           SourceLocation EndLoc) {
9489   if (!AStmt)
9490     return StmtError();
9491 
9492   // OpenMP 5.0, 2.10.1 task Construct
9493   // If a detach clause appears on the directive, then a mergeable clause cannot
9494   // appear on the same directive.
9495   if (checkDetachMergeableClauses(*this, Clauses))
9496     return StmtError();
9497 
9498   auto *CS = cast<CapturedStmt>(AStmt);
9499   // 1.2.2 OpenMP Language Terminology
9500   // Structured block - An executable statement with a single entry at the
9501   // top and a single exit at the bottom.
9502   // The point of exit cannot be a branch out of the structured block.
9503   // longjmp() and throw() must not violate the entry/exit criteria.
9504   CS->getCapturedDecl()->setNothrow();
9505 
9506   setFunctionHasBranchProtectedScope();
9507 
9508   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9509                                   DSAStack->isCancelRegion());
9510 }
9511 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)9512 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9513                                                SourceLocation EndLoc) {
9514   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9515 }
9516 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)9517 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9518                                              SourceLocation EndLoc) {
9519   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9520 }
9521 
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)9522 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9523                                               SourceLocation EndLoc) {
9524   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9525 }
9526 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9527 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9528                                                Stmt *AStmt,
9529                                                SourceLocation StartLoc,
9530                                                SourceLocation EndLoc) {
9531   if (!AStmt)
9532     return StmtError();
9533 
9534   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9535 
9536   setFunctionHasBranchProtectedScope();
9537 
9538   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9539                                        AStmt,
9540                                        DSAStack->getTaskgroupReductionRef());
9541 }
9542 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9543 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9544                                            SourceLocation StartLoc,
9545                                            SourceLocation EndLoc) {
9546   OMPFlushClause *FC = nullptr;
9547   OMPClause *OrderClause = nullptr;
9548   for (OMPClause *C : Clauses) {
9549     if (C->getClauseKind() == OMPC_flush)
9550       FC = cast<OMPFlushClause>(C);
9551     else
9552       OrderClause = C;
9553   }
9554   OpenMPClauseKind MemOrderKind = OMPC_unknown;
9555   SourceLocation MemOrderLoc;
9556   for (const OMPClause *C : Clauses) {
9557     if (C->getClauseKind() == OMPC_acq_rel ||
9558         C->getClauseKind() == OMPC_acquire ||
9559         C->getClauseKind() == OMPC_release) {
9560       if (MemOrderKind != OMPC_unknown) {
9561         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9562             << getOpenMPDirectiveName(OMPD_flush) << 1
9563             << SourceRange(C->getBeginLoc(), C->getEndLoc());
9564         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9565             << getOpenMPClauseName(MemOrderKind);
9566       } else {
9567         MemOrderKind = C->getClauseKind();
9568         MemOrderLoc = C->getBeginLoc();
9569       }
9570     }
9571   }
9572   if (FC && OrderClause) {
9573     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9574         << getOpenMPClauseName(OrderClause->getClauseKind());
9575     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9576         << getOpenMPClauseName(OrderClause->getClauseKind());
9577     return StmtError();
9578   }
9579   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9580 }
9581 
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9582 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9583                                             SourceLocation StartLoc,
9584                                             SourceLocation EndLoc) {
9585   if (Clauses.empty()) {
9586     Diag(StartLoc, diag::err_omp_depobj_expected);
9587     return StmtError();
9588   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9589     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9590     return StmtError();
9591   }
9592   // Only depobj expression and another single clause is allowed.
9593   if (Clauses.size() > 2) {
9594     Diag(Clauses[2]->getBeginLoc(),
9595          diag::err_omp_depobj_single_clause_expected);
9596     return StmtError();
9597   } else if (Clauses.size() < 1) {
9598     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9599     return StmtError();
9600   }
9601   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9602 }
9603 
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9604 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9605                                           SourceLocation StartLoc,
9606                                           SourceLocation EndLoc) {
9607   // Check that exactly one clause is specified.
9608   if (Clauses.size() != 1) {
9609     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9610          diag::err_omp_scan_single_clause_expected);
9611     return StmtError();
9612   }
9613   // Check that scan directive is used in the scopeof the OpenMP loop body.
9614   if (Scope *S = DSAStack->getCurScope()) {
9615     Scope *ParentS = S->getParent();
9616     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9617         !ParentS->getBreakParent()->isOpenMPLoopScope())
9618       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9619                        << getOpenMPDirectiveName(OMPD_scan) << 5);
9620   }
9621   // Check that only one instance of scan directives is used in the same outer
9622   // region.
9623   if (DSAStack->doesParentHasScanDirective()) {
9624     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9625     Diag(DSAStack->getParentScanDirectiveLoc(),
9626          diag::note_omp_previous_directive)
9627         << "scan";
9628     return StmtError();
9629   }
9630   DSAStack->setParentHasScanDirective(StartLoc);
9631   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9632 }
9633 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9634 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9635                                              Stmt *AStmt,
9636                                              SourceLocation StartLoc,
9637                                              SourceLocation EndLoc) {
9638   const OMPClause *DependFound = nullptr;
9639   const OMPClause *DependSourceClause = nullptr;
9640   const OMPClause *DependSinkClause = nullptr;
9641   bool ErrorFound = false;
9642   const OMPThreadsClause *TC = nullptr;
9643   const OMPSIMDClause *SC = nullptr;
9644   for (const OMPClause *C : Clauses) {
9645     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9646       DependFound = C;
9647       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9648         if (DependSourceClause) {
9649           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9650               << getOpenMPDirectiveName(OMPD_ordered)
9651               << getOpenMPClauseName(OMPC_depend) << 2;
9652           ErrorFound = true;
9653         } else {
9654           DependSourceClause = C;
9655         }
9656         if (DependSinkClause) {
9657           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9658               << 0;
9659           ErrorFound = true;
9660         }
9661       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9662         if (DependSourceClause) {
9663           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9664               << 1;
9665           ErrorFound = true;
9666         }
9667         DependSinkClause = C;
9668       }
9669     } else if (C->getClauseKind() == OMPC_threads) {
9670       TC = cast<OMPThreadsClause>(C);
9671     } else if (C->getClauseKind() == OMPC_simd) {
9672       SC = cast<OMPSIMDClause>(C);
9673     }
9674   }
9675   if (!ErrorFound && !SC &&
9676       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
9677     // OpenMP [2.8.1,simd Construct, Restrictions]
9678     // An ordered construct with the simd clause is the only OpenMP construct
9679     // that can appear in the simd region.
9680     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9681         << (LangOpts.OpenMP >= 50 ? 1 : 0);
9682     ErrorFound = true;
9683   } else if (DependFound && (TC || SC)) {
9684     Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9685         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9686     ErrorFound = true;
9687   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
9688     Diag(DependFound->getBeginLoc(),
9689          diag::err_omp_ordered_directive_without_param);
9690     ErrorFound = true;
9691   } else if (TC || Clauses.empty()) {
9692     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
9693       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9694       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9695           << (TC != nullptr);
9696       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9697       ErrorFound = true;
9698     }
9699   }
9700   if ((!AStmt && !DependFound) || ErrorFound)
9701     return StmtError();
9702 
9703   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9704   // During execution of an iteration of a worksharing-loop or a loop nest
9705   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9706   // must not execute more than one ordered region corresponding to an ordered
9707   // construct without a depend clause.
9708   if (!DependFound) {
9709     if (DSAStack->doesParentHasOrderedDirective()) {
9710       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9711       Diag(DSAStack->getParentOrderedDirectiveLoc(),
9712            diag::note_omp_previous_directive)
9713           << "ordered";
9714       return StmtError();
9715     }
9716     DSAStack->setParentHasOrderedDirective(StartLoc);
9717   }
9718 
9719   if (AStmt) {
9720     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9721 
9722     setFunctionHasBranchProtectedScope();
9723   }
9724 
9725   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9726 }
9727 
9728 namespace {
9729 /// Helper class for checking expression in 'omp atomic [update]'
9730 /// construct.
9731 class OpenMPAtomicUpdateChecker {
9732   /// Error results for atomic update expressions.
9733   enum ExprAnalysisErrorCode {
9734     /// A statement is not an expression statement.
9735     NotAnExpression,
9736     /// Expression is not builtin binary or unary operation.
9737     NotABinaryOrUnaryExpression,
9738     /// Unary operation is not post-/pre- increment/decrement operation.
9739     NotAnUnaryIncDecExpression,
9740     /// An expression is not of scalar type.
9741     NotAScalarType,
9742     /// A binary operation is not an assignment operation.
9743     NotAnAssignmentOp,
9744     /// RHS part of the binary operation is not a binary expression.
9745     NotABinaryExpression,
9746     /// RHS part is not additive/multiplicative/shift/biwise binary
9747     /// expression.
9748     NotABinaryOperator,
9749     /// RHS binary operation does not have reference to the updated LHS
9750     /// part.
9751     NotAnUpdateExpression,
9752     /// No errors is found.
9753     NoError
9754   };
9755   /// Reference to Sema.
9756   Sema &SemaRef;
9757   /// A location for note diagnostics (when error is found).
9758   SourceLocation NoteLoc;
9759   /// 'x' lvalue part of the source atomic expression.
9760   Expr *X;
9761   /// 'expr' rvalue part of the source atomic expression.
9762   Expr *E;
9763   /// Helper expression of the form
9764   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9765   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9766   Expr *UpdateExpr;
9767   /// Is 'x' a LHS in a RHS part of full update expression. It is
9768   /// important for non-associative operations.
9769   bool IsXLHSInRHSPart;
9770   BinaryOperatorKind Op;
9771   SourceLocation OpLoc;
9772   /// true if the source expression is a postfix unary operation, false
9773   /// if it is a prefix unary operation.
9774   bool IsPostfixUpdate;
9775 
9776 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)9777   OpenMPAtomicUpdateChecker(Sema &SemaRef)
9778       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9779         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9780   /// Check specified statement that it is suitable for 'atomic update'
9781   /// constructs and extract 'x', 'expr' and Operation from the original
9782   /// expression. If DiagId and NoteId == 0, then only check is performed
9783   /// without error notification.
9784   /// \param DiagId Diagnostic which should be emitted if error is found.
9785   /// \param NoteId Diagnostic note for the main error message.
9786   /// \return true if statement is not an update expression, false otherwise.
9787   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9788   /// Return the 'x' lvalue part of the source atomic expression.
getX() const9789   Expr *getX() const { return X; }
9790   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const9791   Expr *getExpr() const { return E; }
9792   /// Return the update expression used in calculation of the updated
9793   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9794   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const9795   Expr *getUpdateExpr() const { return UpdateExpr; }
9796   /// Return true if 'x' is LHS in RHS part of full update expression,
9797   /// false otherwise.
isXLHSInRHSPart() const9798   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9799 
9800   /// true if the source expression is a postfix unary operation, false
9801   /// if it is a prefix unary operation.
isPostfixUpdate() const9802   bool isPostfixUpdate() const { return IsPostfixUpdate; }
9803 
9804 private:
9805   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9806                             unsigned NoteId = 0);
9807 };
9808 } // namespace
9809 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)9810 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9811     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9812   ExprAnalysisErrorCode ErrorFound = NoError;
9813   SourceLocation ErrorLoc, NoteLoc;
9814   SourceRange ErrorRange, NoteRange;
9815   // Allowed constructs are:
9816   //  x = x binop expr;
9817   //  x = expr binop x;
9818   if (AtomicBinOp->getOpcode() == BO_Assign) {
9819     X = AtomicBinOp->getLHS();
9820     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9821             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9822       if (AtomicInnerBinOp->isMultiplicativeOp() ||
9823           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9824           AtomicInnerBinOp->isBitwiseOp()) {
9825         Op = AtomicInnerBinOp->getOpcode();
9826         OpLoc = AtomicInnerBinOp->getOperatorLoc();
9827         Expr *LHS = AtomicInnerBinOp->getLHS();
9828         Expr *RHS = AtomicInnerBinOp->getRHS();
9829         llvm::FoldingSetNodeID XId, LHSId, RHSId;
9830         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9831                                           /*Canonical=*/true);
9832         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9833                                             /*Canonical=*/true);
9834         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9835                                             /*Canonical=*/true);
9836         if (XId == LHSId) {
9837           E = RHS;
9838           IsXLHSInRHSPart = true;
9839         } else if (XId == RHSId) {
9840           E = LHS;
9841           IsXLHSInRHSPart = false;
9842         } else {
9843           ErrorLoc = AtomicInnerBinOp->getExprLoc();
9844           ErrorRange = AtomicInnerBinOp->getSourceRange();
9845           NoteLoc = X->getExprLoc();
9846           NoteRange = X->getSourceRange();
9847           ErrorFound = NotAnUpdateExpression;
9848         }
9849       } else {
9850         ErrorLoc = AtomicInnerBinOp->getExprLoc();
9851         ErrorRange = AtomicInnerBinOp->getSourceRange();
9852         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9853         NoteRange = SourceRange(NoteLoc, NoteLoc);
9854         ErrorFound = NotABinaryOperator;
9855       }
9856     } else {
9857       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9858       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9859       ErrorFound = NotABinaryExpression;
9860     }
9861   } else {
9862     ErrorLoc = AtomicBinOp->getExprLoc();
9863     ErrorRange = AtomicBinOp->getSourceRange();
9864     NoteLoc = AtomicBinOp->getOperatorLoc();
9865     NoteRange = SourceRange(NoteLoc, NoteLoc);
9866     ErrorFound = NotAnAssignmentOp;
9867   }
9868   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9869     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9870     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9871     return true;
9872   }
9873   if (SemaRef.CurContext->isDependentContext())
9874     E = X = UpdateExpr = nullptr;
9875   return ErrorFound != NoError;
9876 }
9877 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)9878 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9879                                                unsigned NoteId) {
9880   ExprAnalysisErrorCode ErrorFound = NoError;
9881   SourceLocation ErrorLoc, NoteLoc;
9882   SourceRange ErrorRange, NoteRange;
9883   // Allowed constructs are:
9884   //  x++;
9885   //  x--;
9886   //  ++x;
9887   //  --x;
9888   //  x binop= expr;
9889   //  x = x binop expr;
9890   //  x = expr binop x;
9891   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9892     AtomicBody = AtomicBody->IgnoreParenImpCasts();
9893     if (AtomicBody->getType()->isScalarType() ||
9894         AtomicBody->isInstantiationDependent()) {
9895       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9896               AtomicBody->IgnoreParenImpCasts())) {
9897         // Check for Compound Assignment Operation
9898         Op = BinaryOperator::getOpForCompoundAssignment(
9899             AtomicCompAssignOp->getOpcode());
9900         OpLoc = AtomicCompAssignOp->getOperatorLoc();
9901         E = AtomicCompAssignOp->getRHS();
9902         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9903         IsXLHSInRHSPart = true;
9904       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9905                      AtomicBody->IgnoreParenImpCasts())) {
9906         // Check for Binary Operation
9907         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9908           return true;
9909       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9910                      AtomicBody->IgnoreParenImpCasts())) {
9911         // Check for Unary Operation
9912         if (AtomicUnaryOp->isIncrementDecrementOp()) {
9913           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9914           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9915           OpLoc = AtomicUnaryOp->getOperatorLoc();
9916           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9917           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9918           IsXLHSInRHSPart = true;
9919         } else {
9920           ErrorFound = NotAnUnaryIncDecExpression;
9921           ErrorLoc = AtomicUnaryOp->getExprLoc();
9922           ErrorRange = AtomicUnaryOp->getSourceRange();
9923           NoteLoc = AtomicUnaryOp->getOperatorLoc();
9924           NoteRange = SourceRange(NoteLoc, NoteLoc);
9925         }
9926       } else if (!AtomicBody->isInstantiationDependent()) {
9927         ErrorFound = NotABinaryOrUnaryExpression;
9928         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9929         NoteRange = ErrorRange = AtomicBody->getSourceRange();
9930       }
9931     } else {
9932       ErrorFound = NotAScalarType;
9933       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9934       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9935     }
9936   } else {
9937     ErrorFound = NotAnExpression;
9938     NoteLoc = ErrorLoc = S->getBeginLoc();
9939     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9940   }
9941   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9942     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9943     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9944     return true;
9945   }
9946   if (SemaRef.CurContext->isDependentContext())
9947     E = X = UpdateExpr = nullptr;
9948   if (ErrorFound == NoError && E && X) {
9949     // Build an update expression of form 'OpaqueValueExpr(x) binop
9950     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9951     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9952     auto *OVEX = new (SemaRef.getASTContext())
9953         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9954     auto *OVEExpr = new (SemaRef.getASTContext())
9955         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9956     ExprResult Update =
9957         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9958                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
9959     if (Update.isInvalid())
9960       return true;
9961     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9962                                                Sema::AA_Casting);
9963     if (Update.isInvalid())
9964       return true;
9965     UpdateExpr = Update.get();
9966   }
9967   return ErrorFound != NoError;
9968 }
9969 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9970 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9971                                             Stmt *AStmt,
9972                                             SourceLocation StartLoc,
9973                                             SourceLocation EndLoc) {
9974   // Register location of the first atomic directive.
9975   DSAStack->addAtomicDirectiveLoc(StartLoc);
9976   if (!AStmt)
9977     return StmtError();
9978 
9979   // 1.2.2 OpenMP Language Terminology
9980   // Structured block - An executable statement with a single entry at the
9981   // top and a single exit at the bottom.
9982   // The point of exit cannot be a branch out of the structured block.
9983   // longjmp() and throw() must not violate the entry/exit criteria.
9984   OpenMPClauseKind AtomicKind = OMPC_unknown;
9985   SourceLocation AtomicKindLoc;
9986   OpenMPClauseKind MemOrderKind = OMPC_unknown;
9987   SourceLocation MemOrderLoc;
9988   for (const OMPClause *C : Clauses) {
9989     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9990         C->getClauseKind() == OMPC_update ||
9991         C->getClauseKind() == OMPC_capture) {
9992       if (AtomicKind != OMPC_unknown) {
9993         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9994             << SourceRange(C->getBeginLoc(), C->getEndLoc());
9995         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9996             << getOpenMPClauseName(AtomicKind);
9997       } else {
9998         AtomicKind = C->getClauseKind();
9999         AtomicKindLoc = C->getBeginLoc();
10000       }
10001     }
10002     if (C->getClauseKind() == OMPC_seq_cst ||
10003         C->getClauseKind() == OMPC_acq_rel ||
10004         C->getClauseKind() == OMPC_acquire ||
10005         C->getClauseKind() == OMPC_release ||
10006         C->getClauseKind() == OMPC_relaxed) {
10007       if (MemOrderKind != OMPC_unknown) {
10008         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10009             << getOpenMPDirectiveName(OMPD_atomic) << 0
10010             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10011         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10012             << getOpenMPClauseName(MemOrderKind);
10013       } else {
10014         MemOrderKind = C->getClauseKind();
10015         MemOrderLoc = C->getBeginLoc();
10016       }
10017     }
10018   }
10019   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10020   // If atomic-clause is read then memory-order-clause must not be acq_rel or
10021   // release.
10022   // If atomic-clause is write then memory-order-clause must not be acq_rel or
10023   // acquire.
10024   // If atomic-clause is update or not present then memory-order-clause must not
10025   // be acq_rel or acquire.
10026   if ((AtomicKind == OMPC_read &&
10027        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10028       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10029         AtomicKind == OMPC_unknown) &&
10030        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10031     SourceLocation Loc = AtomicKindLoc;
10032     if (AtomicKind == OMPC_unknown)
10033       Loc = StartLoc;
10034     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10035         << getOpenMPClauseName(AtomicKind)
10036         << (AtomicKind == OMPC_unknown ? 1 : 0)
10037         << getOpenMPClauseName(MemOrderKind);
10038     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10039         << getOpenMPClauseName(MemOrderKind);
10040   }
10041 
10042   Stmt *Body = AStmt;
10043   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10044     Body = EWC->getSubExpr();
10045 
10046   Expr *X = nullptr;
10047   Expr *V = nullptr;
10048   Expr *E = nullptr;
10049   Expr *UE = nullptr;
10050   bool IsXLHSInRHSPart = false;
10051   bool IsPostfixUpdate = false;
10052   // OpenMP [2.12.6, atomic Construct]
10053   // In the next expressions:
10054   // * x and v (as applicable) are both l-value expressions with scalar type.
10055   // * During the execution of an atomic region, multiple syntactic
10056   // occurrences of x must designate the same storage location.
10057   // * Neither of v and expr (as applicable) may access the storage location
10058   // designated by x.
10059   // * Neither of x and expr (as applicable) may access the storage location
10060   // designated by v.
10061   // * expr is an expression with scalar type.
10062   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10063   // * binop, binop=, ++, and -- are not overloaded operators.
10064   // * The expression x binop expr must be numerically equivalent to x binop
10065   // (expr). This requirement is satisfied if the operators in expr have
10066   // precedence greater than binop, or by using parentheses around expr or
10067   // subexpressions of expr.
10068   // * The expression expr binop x must be numerically equivalent to (expr)
10069   // binop x. This requirement is satisfied if the operators in expr have
10070   // precedence equal to or greater than binop, or by using parentheses around
10071   // expr or subexpressions of expr.
10072   // * For forms that allow multiple occurrences of x, the number of times
10073   // that x is evaluated is unspecified.
10074   if (AtomicKind == OMPC_read) {
10075     enum {
10076       NotAnExpression,
10077       NotAnAssignmentOp,
10078       NotAScalarType,
10079       NotAnLValue,
10080       NoError
10081     } ErrorFound = NoError;
10082     SourceLocation ErrorLoc, NoteLoc;
10083     SourceRange ErrorRange, NoteRange;
10084     // If clause is read:
10085     //  v = x;
10086     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10087       const auto *AtomicBinOp =
10088           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10089       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10090         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10091         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10092         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10093             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10094           if (!X->isLValue() || !V->isLValue()) {
10095             const Expr *NotLValueExpr = X->isLValue() ? V : X;
10096             ErrorFound = NotAnLValue;
10097             ErrorLoc = AtomicBinOp->getExprLoc();
10098             ErrorRange = AtomicBinOp->getSourceRange();
10099             NoteLoc = NotLValueExpr->getExprLoc();
10100             NoteRange = NotLValueExpr->getSourceRange();
10101           }
10102         } else if (!X->isInstantiationDependent() ||
10103                    !V->isInstantiationDependent()) {
10104           const Expr *NotScalarExpr =
10105               (X->isInstantiationDependent() || X->getType()->isScalarType())
10106                   ? V
10107                   : X;
10108           ErrorFound = NotAScalarType;
10109           ErrorLoc = AtomicBinOp->getExprLoc();
10110           ErrorRange = AtomicBinOp->getSourceRange();
10111           NoteLoc = NotScalarExpr->getExprLoc();
10112           NoteRange = NotScalarExpr->getSourceRange();
10113         }
10114       } else if (!AtomicBody->isInstantiationDependent()) {
10115         ErrorFound = NotAnAssignmentOp;
10116         ErrorLoc = AtomicBody->getExprLoc();
10117         ErrorRange = AtomicBody->getSourceRange();
10118         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10119                               : AtomicBody->getExprLoc();
10120         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10121                                 : AtomicBody->getSourceRange();
10122       }
10123     } else {
10124       ErrorFound = NotAnExpression;
10125       NoteLoc = ErrorLoc = Body->getBeginLoc();
10126       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10127     }
10128     if (ErrorFound != NoError) {
10129       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10130           << ErrorRange;
10131       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10132                                                       << NoteRange;
10133       return StmtError();
10134     }
10135     if (CurContext->isDependentContext())
10136       V = X = nullptr;
10137   } else if (AtomicKind == OMPC_write) {
10138     enum {
10139       NotAnExpression,
10140       NotAnAssignmentOp,
10141       NotAScalarType,
10142       NotAnLValue,
10143       NoError
10144     } ErrorFound = NoError;
10145     SourceLocation ErrorLoc, NoteLoc;
10146     SourceRange ErrorRange, NoteRange;
10147     // If clause is write:
10148     //  x = expr;
10149     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10150       const auto *AtomicBinOp =
10151           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10152       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10153         X = AtomicBinOp->getLHS();
10154         E = AtomicBinOp->getRHS();
10155         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10156             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10157           if (!X->isLValue()) {
10158             ErrorFound = NotAnLValue;
10159             ErrorLoc = AtomicBinOp->getExprLoc();
10160             ErrorRange = AtomicBinOp->getSourceRange();
10161             NoteLoc = X->getExprLoc();
10162             NoteRange = X->getSourceRange();
10163           }
10164         } else if (!X->isInstantiationDependent() ||
10165                    !E->isInstantiationDependent()) {
10166           const Expr *NotScalarExpr =
10167               (X->isInstantiationDependent() || X->getType()->isScalarType())
10168                   ? E
10169                   : X;
10170           ErrorFound = NotAScalarType;
10171           ErrorLoc = AtomicBinOp->getExprLoc();
10172           ErrorRange = AtomicBinOp->getSourceRange();
10173           NoteLoc = NotScalarExpr->getExprLoc();
10174           NoteRange = NotScalarExpr->getSourceRange();
10175         }
10176       } else if (!AtomicBody->isInstantiationDependent()) {
10177         ErrorFound = NotAnAssignmentOp;
10178         ErrorLoc = AtomicBody->getExprLoc();
10179         ErrorRange = AtomicBody->getSourceRange();
10180         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10181                               : AtomicBody->getExprLoc();
10182         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10183                                 : AtomicBody->getSourceRange();
10184       }
10185     } else {
10186       ErrorFound = NotAnExpression;
10187       NoteLoc = ErrorLoc = Body->getBeginLoc();
10188       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10189     }
10190     if (ErrorFound != NoError) {
10191       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10192           << ErrorRange;
10193       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10194                                                       << NoteRange;
10195       return StmtError();
10196     }
10197     if (CurContext->isDependentContext())
10198       E = X = nullptr;
10199   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10200     // If clause is update:
10201     //  x++;
10202     //  x--;
10203     //  ++x;
10204     //  --x;
10205     //  x binop= expr;
10206     //  x = x binop expr;
10207     //  x = expr binop x;
10208     OpenMPAtomicUpdateChecker Checker(*this);
10209     if (Checker.checkStatement(
10210             Body, (AtomicKind == OMPC_update)
10211                       ? diag::err_omp_atomic_update_not_expression_statement
10212                       : diag::err_omp_atomic_not_expression_statement,
10213             diag::note_omp_atomic_update))
10214       return StmtError();
10215     if (!CurContext->isDependentContext()) {
10216       E = Checker.getExpr();
10217       X = Checker.getX();
10218       UE = Checker.getUpdateExpr();
10219       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10220     }
10221   } else if (AtomicKind == OMPC_capture) {
10222     enum {
10223       NotAnAssignmentOp,
10224       NotACompoundStatement,
10225       NotTwoSubstatements,
10226       NotASpecificExpression,
10227       NoError
10228     } ErrorFound = NoError;
10229     SourceLocation ErrorLoc, NoteLoc;
10230     SourceRange ErrorRange, NoteRange;
10231     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10232       // If clause is a capture:
10233       //  v = x++;
10234       //  v = x--;
10235       //  v = ++x;
10236       //  v = --x;
10237       //  v = x binop= expr;
10238       //  v = x = x binop expr;
10239       //  v = x = expr binop x;
10240       const auto *AtomicBinOp =
10241           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10242       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10243         V = AtomicBinOp->getLHS();
10244         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10245         OpenMPAtomicUpdateChecker Checker(*this);
10246         if (Checker.checkStatement(
10247                 Body, diag::err_omp_atomic_capture_not_expression_statement,
10248                 diag::note_omp_atomic_update))
10249           return StmtError();
10250         E = Checker.getExpr();
10251         X = Checker.getX();
10252         UE = Checker.getUpdateExpr();
10253         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10254         IsPostfixUpdate = Checker.isPostfixUpdate();
10255       } else if (!AtomicBody->isInstantiationDependent()) {
10256         ErrorLoc = AtomicBody->getExprLoc();
10257         ErrorRange = AtomicBody->getSourceRange();
10258         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10259                               : AtomicBody->getExprLoc();
10260         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10261                                 : AtomicBody->getSourceRange();
10262         ErrorFound = NotAnAssignmentOp;
10263       }
10264       if (ErrorFound != NoError) {
10265         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10266             << ErrorRange;
10267         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10268         return StmtError();
10269       }
10270       if (CurContext->isDependentContext())
10271         UE = V = E = X = nullptr;
10272     } else {
10273       // If clause is a capture:
10274       //  { v = x; x = expr; }
10275       //  { v = x; x++; }
10276       //  { v = x; x--; }
10277       //  { v = x; ++x; }
10278       //  { v = x; --x; }
10279       //  { v = x; x binop= expr; }
10280       //  { v = x; x = x binop expr; }
10281       //  { v = x; x = expr binop x; }
10282       //  { x++; v = x; }
10283       //  { x--; v = x; }
10284       //  { ++x; v = x; }
10285       //  { --x; v = x; }
10286       //  { x binop= expr; v = x; }
10287       //  { x = x binop expr; v = x; }
10288       //  { x = expr binop x; v = x; }
10289       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10290         // Check that this is { expr1; expr2; }
10291         if (CS->size() == 2) {
10292           Stmt *First = CS->body_front();
10293           Stmt *Second = CS->body_back();
10294           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10295             First = EWC->getSubExpr()->IgnoreParenImpCasts();
10296           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10297             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10298           // Need to find what subexpression is 'v' and what is 'x'.
10299           OpenMPAtomicUpdateChecker Checker(*this);
10300           bool IsUpdateExprFound = !Checker.checkStatement(Second);
10301           BinaryOperator *BinOp = nullptr;
10302           if (IsUpdateExprFound) {
10303             BinOp = dyn_cast<BinaryOperator>(First);
10304             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10305           }
10306           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10307             //  { v = x; x++; }
10308             //  { v = x; x--; }
10309             //  { v = x; ++x; }
10310             //  { v = x; --x; }
10311             //  { v = x; x binop= expr; }
10312             //  { v = x; x = x binop expr; }
10313             //  { v = x; x = expr binop x; }
10314             // Check that the first expression has form v = x.
10315             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10316             llvm::FoldingSetNodeID XId, PossibleXId;
10317             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10318             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10319             IsUpdateExprFound = XId == PossibleXId;
10320             if (IsUpdateExprFound) {
10321               V = BinOp->getLHS();
10322               X = Checker.getX();
10323               E = Checker.getExpr();
10324               UE = Checker.getUpdateExpr();
10325               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10326               IsPostfixUpdate = true;
10327             }
10328           }
10329           if (!IsUpdateExprFound) {
10330             IsUpdateExprFound = !Checker.checkStatement(First);
10331             BinOp = nullptr;
10332             if (IsUpdateExprFound) {
10333               BinOp = dyn_cast<BinaryOperator>(Second);
10334               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10335             }
10336             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10337               //  { x++; v = x; }
10338               //  { x--; v = x; }
10339               //  { ++x; v = x; }
10340               //  { --x; v = x; }
10341               //  { x binop= expr; v = x; }
10342               //  { x = x binop expr; v = x; }
10343               //  { x = expr binop x; v = x; }
10344               // Check that the second expression has form v = x.
10345               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10346               llvm::FoldingSetNodeID XId, PossibleXId;
10347               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10348               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10349               IsUpdateExprFound = XId == PossibleXId;
10350               if (IsUpdateExprFound) {
10351                 V = BinOp->getLHS();
10352                 X = Checker.getX();
10353                 E = Checker.getExpr();
10354                 UE = Checker.getUpdateExpr();
10355                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10356                 IsPostfixUpdate = false;
10357               }
10358             }
10359           }
10360           if (!IsUpdateExprFound) {
10361             //  { v = x; x = expr; }
10362             auto *FirstExpr = dyn_cast<Expr>(First);
10363             auto *SecondExpr = dyn_cast<Expr>(Second);
10364             if (!FirstExpr || !SecondExpr ||
10365                 !(FirstExpr->isInstantiationDependent() ||
10366                   SecondExpr->isInstantiationDependent())) {
10367               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10368               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10369                 ErrorFound = NotAnAssignmentOp;
10370                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10371                                                 : First->getBeginLoc();
10372                 NoteRange = ErrorRange = FirstBinOp
10373                                              ? FirstBinOp->getSourceRange()
10374                                              : SourceRange(ErrorLoc, ErrorLoc);
10375               } else {
10376                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10377                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10378                   ErrorFound = NotAnAssignmentOp;
10379                   NoteLoc = ErrorLoc = SecondBinOp
10380                                            ? SecondBinOp->getOperatorLoc()
10381                                            : Second->getBeginLoc();
10382                   NoteRange = ErrorRange =
10383                       SecondBinOp ? SecondBinOp->getSourceRange()
10384                                   : SourceRange(ErrorLoc, ErrorLoc);
10385                 } else {
10386                   Expr *PossibleXRHSInFirst =
10387                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
10388                   Expr *PossibleXLHSInSecond =
10389                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
10390                   llvm::FoldingSetNodeID X1Id, X2Id;
10391                   PossibleXRHSInFirst->Profile(X1Id, Context,
10392                                                /*Canonical=*/true);
10393                   PossibleXLHSInSecond->Profile(X2Id, Context,
10394                                                 /*Canonical=*/true);
10395                   IsUpdateExprFound = X1Id == X2Id;
10396                   if (IsUpdateExprFound) {
10397                     V = FirstBinOp->getLHS();
10398                     X = SecondBinOp->getLHS();
10399                     E = SecondBinOp->getRHS();
10400                     UE = nullptr;
10401                     IsXLHSInRHSPart = false;
10402                     IsPostfixUpdate = true;
10403                   } else {
10404                     ErrorFound = NotASpecificExpression;
10405                     ErrorLoc = FirstBinOp->getExprLoc();
10406                     ErrorRange = FirstBinOp->getSourceRange();
10407                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10408                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
10409                   }
10410                 }
10411               }
10412             }
10413           }
10414         } else {
10415           NoteLoc = ErrorLoc = Body->getBeginLoc();
10416           NoteRange = ErrorRange =
10417               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10418           ErrorFound = NotTwoSubstatements;
10419         }
10420       } else {
10421         NoteLoc = ErrorLoc = Body->getBeginLoc();
10422         NoteRange = ErrorRange =
10423             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10424         ErrorFound = NotACompoundStatement;
10425       }
10426       if (ErrorFound != NoError) {
10427         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10428             << ErrorRange;
10429         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10430         return StmtError();
10431       }
10432       if (CurContext->isDependentContext())
10433         UE = V = E = X = nullptr;
10434     }
10435   }
10436 
10437   setFunctionHasBranchProtectedScope();
10438 
10439   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10440                                     X, V, E, UE, IsXLHSInRHSPart,
10441                                     IsPostfixUpdate);
10442 }
10443 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10444 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10445                                             Stmt *AStmt,
10446                                             SourceLocation StartLoc,
10447                                             SourceLocation EndLoc) {
10448   if (!AStmt)
10449     return StmtError();
10450 
10451   auto *CS = cast<CapturedStmt>(AStmt);
10452   // 1.2.2 OpenMP Language Terminology
10453   // Structured block - An executable statement with a single entry at the
10454   // top and a single exit at the bottom.
10455   // The point of exit cannot be a branch out of the structured block.
10456   // longjmp() and throw() must not violate the entry/exit criteria.
10457   CS->getCapturedDecl()->setNothrow();
10458   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10459        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10460     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10461     // 1.2.2 OpenMP Language Terminology
10462     // Structured block - An executable statement with a single entry at the
10463     // top and a single exit at the bottom.
10464     // The point of exit cannot be a branch out of the structured block.
10465     // longjmp() and throw() must not violate the entry/exit criteria.
10466     CS->getCapturedDecl()->setNothrow();
10467   }
10468 
10469   // OpenMP [2.16, Nesting of Regions]
10470   // If specified, a teams construct must be contained within a target
10471   // construct. That target construct must contain no statements or directives
10472   // outside of the teams construct.
10473   if (DSAStack->hasInnerTeamsRegion()) {
10474     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10475     bool OMPTeamsFound = true;
10476     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10477       auto I = CS->body_begin();
10478       while (I != CS->body_end()) {
10479         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10480         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10481             OMPTeamsFound) {
10482 
10483           OMPTeamsFound = false;
10484           break;
10485         }
10486         ++I;
10487       }
10488       assert(I != CS->body_end() && "Not found statement");
10489       S = *I;
10490     } else {
10491       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10492       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10493     }
10494     if (!OMPTeamsFound) {
10495       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10496       Diag(DSAStack->getInnerTeamsRegionLoc(),
10497            diag::note_omp_nested_teams_construct_here);
10498       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10499           << isa<OMPExecutableDirective>(S);
10500       return StmtError();
10501     }
10502   }
10503 
10504   setFunctionHasBranchProtectedScope();
10505 
10506   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10507 }
10508 
10509 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10510 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10511                                          Stmt *AStmt, SourceLocation StartLoc,
10512                                          SourceLocation EndLoc) {
10513   if (!AStmt)
10514     return StmtError();
10515 
10516   auto *CS = cast<CapturedStmt>(AStmt);
10517   // 1.2.2 OpenMP Language Terminology
10518   // Structured block - An executable statement with a single entry at the
10519   // top and a single exit at the bottom.
10520   // The point of exit cannot be a branch out of the structured block.
10521   // longjmp() and throw() must not violate the entry/exit criteria.
10522   CS->getCapturedDecl()->setNothrow();
10523   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10524        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10525     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10526     // 1.2.2 OpenMP Language Terminology
10527     // Structured block - An executable statement with a single entry at the
10528     // top and a single exit at the bottom.
10529     // The point of exit cannot be a branch out of the structured block.
10530     // longjmp() and throw() must not violate the entry/exit criteria.
10531     CS->getCapturedDecl()->setNothrow();
10532   }
10533 
10534   setFunctionHasBranchProtectedScope();
10535 
10536   return OMPTargetParallelDirective::Create(
10537       Context, StartLoc, EndLoc, Clauses, AStmt,
10538       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10539 }
10540 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10541 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10542     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10543     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10544   if (!AStmt)
10545     return StmtError();
10546 
10547   auto *CS = cast<CapturedStmt>(AStmt);
10548   // 1.2.2 OpenMP Language Terminology
10549   // Structured block - An executable statement with a single entry at the
10550   // top and a single exit at the bottom.
10551   // The point of exit cannot be a branch out of the structured block.
10552   // longjmp() and throw() must not violate the entry/exit criteria.
10553   CS->getCapturedDecl()->setNothrow();
10554   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10555        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10556     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10557     // 1.2.2 OpenMP Language Terminology
10558     // Structured block - An executable statement with a single entry at the
10559     // top and a single exit at the bottom.
10560     // The point of exit cannot be a branch out of the structured block.
10561     // longjmp() and throw() must not violate the entry/exit criteria.
10562     CS->getCapturedDecl()->setNothrow();
10563   }
10564 
10565   OMPLoopDirective::HelperExprs B;
10566   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10567   // define the nested loops number.
10568   unsigned NestedLoopCount =
10569       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10570                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10571                       VarsWithImplicitDSA, B);
10572   if (NestedLoopCount == 0)
10573     return StmtError();
10574 
10575   assert((CurContext->isDependentContext() || B.builtAll()) &&
10576          "omp target parallel for loop exprs were not built");
10577 
10578   if (!CurContext->isDependentContext()) {
10579     // Finalize the clauses that need pre-built expressions for CodeGen.
10580     for (OMPClause *C : Clauses) {
10581       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10582         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10583                                      B.NumIterations, *this, CurScope,
10584                                      DSAStack))
10585           return StmtError();
10586     }
10587   }
10588 
10589   setFunctionHasBranchProtectedScope();
10590   return OMPTargetParallelForDirective::Create(
10591       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10592       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10593 }
10594 
10595 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)10596 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10597                        const OpenMPClauseKind K) {
10598   return llvm::any_of(
10599       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10600 }
10601 
10602 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)10603 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10604                        const Params... ClauseTypes) {
10605   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10606 }
10607 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10608 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10609                                                 Stmt *AStmt,
10610                                                 SourceLocation StartLoc,
10611                                                 SourceLocation EndLoc) {
10612   if (!AStmt)
10613     return StmtError();
10614 
10615   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10616 
10617   // OpenMP [2.12.2, target data Construct, Restrictions]
10618   // At least one map, use_device_addr or use_device_ptr clause must appear on
10619   // the directive.
10620   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10621       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10622     StringRef Expected;
10623     if (LangOpts.OpenMP < 50)
10624       Expected = "'map' or 'use_device_ptr'";
10625     else
10626       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10627     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10628         << Expected << getOpenMPDirectiveName(OMPD_target_data);
10629     return StmtError();
10630   }
10631 
10632   setFunctionHasBranchProtectedScope();
10633 
10634   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10635                                         AStmt);
10636 }
10637 
10638 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10639 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10640                                           SourceLocation StartLoc,
10641                                           SourceLocation EndLoc, Stmt *AStmt) {
10642   if (!AStmt)
10643     return StmtError();
10644 
10645   auto *CS = cast<CapturedStmt>(AStmt);
10646   // 1.2.2 OpenMP Language Terminology
10647   // Structured block - An executable statement with a single entry at the
10648   // top and a single exit at the bottom.
10649   // The point of exit cannot be a branch out of the structured block.
10650   // longjmp() and throw() must not violate the entry/exit criteria.
10651   CS->getCapturedDecl()->setNothrow();
10652   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10653        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10654     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10655     // 1.2.2 OpenMP Language Terminology
10656     // Structured block - An executable statement with a single entry at the
10657     // top and a single exit at the bottom.
10658     // The point of exit cannot be a branch out of the structured block.
10659     // longjmp() and throw() must not violate the entry/exit criteria.
10660     CS->getCapturedDecl()->setNothrow();
10661   }
10662 
10663   // OpenMP [2.10.2, Restrictions, p. 99]
10664   // At least one map clause must appear on the directive.
10665   if (!hasClauses(Clauses, OMPC_map)) {
10666     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10667         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10668     return StmtError();
10669   }
10670 
10671   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10672                                              AStmt);
10673 }
10674 
10675 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10676 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10677                                          SourceLocation StartLoc,
10678                                          SourceLocation EndLoc, Stmt *AStmt) {
10679   if (!AStmt)
10680     return StmtError();
10681 
10682   auto *CS = cast<CapturedStmt>(AStmt);
10683   // 1.2.2 OpenMP Language Terminology
10684   // Structured block - An executable statement with a single entry at the
10685   // top and a single exit at the bottom.
10686   // The point of exit cannot be a branch out of the structured block.
10687   // longjmp() and throw() must not violate the entry/exit criteria.
10688   CS->getCapturedDecl()->setNothrow();
10689   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10690        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10691     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10692     // 1.2.2 OpenMP Language Terminology
10693     // Structured block - An executable statement with a single entry at the
10694     // top and a single exit at the bottom.
10695     // The point of exit cannot be a branch out of the structured block.
10696     // longjmp() and throw() must not violate the entry/exit criteria.
10697     CS->getCapturedDecl()->setNothrow();
10698   }
10699 
10700   // OpenMP [2.10.3, Restrictions, p. 102]
10701   // At least one map clause must appear on the directive.
10702   if (!hasClauses(Clauses, OMPC_map)) {
10703     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10704         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10705     return StmtError();
10706   }
10707 
10708   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10709                                             AStmt);
10710 }
10711 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10712 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10713                                                   SourceLocation StartLoc,
10714                                                   SourceLocation EndLoc,
10715                                                   Stmt *AStmt) {
10716   if (!AStmt)
10717     return StmtError();
10718 
10719   auto *CS = cast<CapturedStmt>(AStmt);
10720   // 1.2.2 OpenMP Language Terminology
10721   // Structured block - An executable statement with a single entry at the
10722   // top and a single exit at the bottom.
10723   // The point of exit cannot be a branch out of the structured block.
10724   // longjmp() and throw() must not violate the entry/exit criteria.
10725   CS->getCapturedDecl()->setNothrow();
10726   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10727        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10728     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10729     // 1.2.2 OpenMP Language Terminology
10730     // Structured block - An executable statement with a single entry at the
10731     // top and a single exit at the bottom.
10732     // The point of exit cannot be a branch out of the structured block.
10733     // longjmp() and throw() must not violate the entry/exit criteria.
10734     CS->getCapturedDecl()->setNothrow();
10735   }
10736 
10737   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10738     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10739     return StmtError();
10740   }
10741   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10742                                           AStmt);
10743 }
10744 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10745 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10746                                            Stmt *AStmt, SourceLocation StartLoc,
10747                                            SourceLocation EndLoc) {
10748   if (!AStmt)
10749     return StmtError();
10750 
10751   auto *CS = cast<CapturedStmt>(AStmt);
10752   // 1.2.2 OpenMP Language Terminology
10753   // Structured block - An executable statement with a single entry at the
10754   // top and a single exit at the bottom.
10755   // The point of exit cannot be a branch out of the structured block.
10756   // longjmp() and throw() must not violate the entry/exit criteria.
10757   CS->getCapturedDecl()->setNothrow();
10758 
10759   setFunctionHasBranchProtectedScope();
10760 
10761   DSAStack->setParentTeamsRegionLoc(StartLoc);
10762 
10763   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10764 }
10765 
10766 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)10767 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10768                                             SourceLocation EndLoc,
10769                                             OpenMPDirectiveKind CancelRegion) {
10770   if (DSAStack->isParentNowaitRegion()) {
10771     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10772     return StmtError();
10773   }
10774   if (DSAStack->isParentOrderedRegion()) {
10775     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10776     return StmtError();
10777   }
10778   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10779                                                CancelRegion);
10780 }
10781 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)10782 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10783                                             SourceLocation StartLoc,
10784                                             SourceLocation EndLoc,
10785                                             OpenMPDirectiveKind CancelRegion) {
10786   if (DSAStack->isParentNowaitRegion()) {
10787     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10788     return StmtError();
10789   }
10790   if (DSAStack->isParentOrderedRegion()) {
10791     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10792     return StmtError();
10793   }
10794   DSAStack->setParentCancelRegion(/*Cancel=*/true);
10795   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10796                                     CancelRegion);
10797 }
10798 
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)10799 static bool checkGrainsizeNumTasksClauses(Sema &S,
10800                                           ArrayRef<OMPClause *> Clauses) {
10801   const OMPClause *PrevClause = nullptr;
10802   bool ErrorFound = false;
10803   for (const OMPClause *C : Clauses) {
10804     if (C->getClauseKind() == OMPC_grainsize ||
10805         C->getClauseKind() == OMPC_num_tasks) {
10806       if (!PrevClause)
10807         PrevClause = C;
10808       else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10809         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10810             << getOpenMPClauseName(C->getClauseKind())
10811             << getOpenMPClauseName(PrevClause->getClauseKind());
10812         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10813             << getOpenMPClauseName(PrevClause->getClauseKind());
10814         ErrorFound = true;
10815       }
10816     }
10817   }
10818   return ErrorFound;
10819 }
10820 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)10821 static bool checkReductionClauseWithNogroup(Sema &S,
10822                                             ArrayRef<OMPClause *> Clauses) {
10823   const OMPClause *ReductionClause = nullptr;
10824   const OMPClause *NogroupClause = nullptr;
10825   for (const OMPClause *C : Clauses) {
10826     if (C->getClauseKind() == OMPC_reduction) {
10827       ReductionClause = C;
10828       if (NogroupClause)
10829         break;
10830       continue;
10831     }
10832     if (C->getClauseKind() == OMPC_nogroup) {
10833       NogroupClause = C;
10834       if (ReductionClause)
10835         break;
10836       continue;
10837     }
10838   }
10839   if (ReductionClause && NogroupClause) {
10840     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10841         << SourceRange(NogroupClause->getBeginLoc(),
10842                        NogroupClause->getEndLoc());
10843     return true;
10844   }
10845   return false;
10846 }
10847 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10848 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10849     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10850     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10851   if (!AStmt)
10852     return StmtError();
10853 
10854   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10855   OMPLoopDirective::HelperExprs B;
10856   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10857   // define the nested loops number.
10858   unsigned NestedLoopCount =
10859       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10860                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10861                       VarsWithImplicitDSA, B);
10862   if (NestedLoopCount == 0)
10863     return StmtError();
10864 
10865   assert((CurContext->isDependentContext() || B.builtAll()) &&
10866          "omp for loop exprs were not built");
10867 
10868   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10869   // The grainsize clause and num_tasks clause are mutually exclusive and may
10870   // not appear on the same taskloop directive.
10871   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10872     return StmtError();
10873   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10874   // If a reduction clause is present on the taskloop directive, the nogroup
10875   // clause must not be specified.
10876   if (checkReductionClauseWithNogroup(*this, Clauses))
10877     return StmtError();
10878 
10879   setFunctionHasBranchProtectedScope();
10880   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10881                                       NestedLoopCount, Clauses, AStmt, B,
10882                                       DSAStack->isCancelRegion());
10883 }
10884 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10885 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10886     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10887     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10888   if (!AStmt)
10889     return StmtError();
10890 
10891   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10892   OMPLoopDirective::HelperExprs B;
10893   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10894   // define the nested loops number.
10895   unsigned NestedLoopCount =
10896       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10897                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10898                       VarsWithImplicitDSA, B);
10899   if (NestedLoopCount == 0)
10900     return StmtError();
10901 
10902   assert((CurContext->isDependentContext() || B.builtAll()) &&
10903          "omp for loop exprs were not built");
10904 
10905   if (!CurContext->isDependentContext()) {
10906     // Finalize the clauses that need pre-built expressions for CodeGen.
10907     for (OMPClause *C : Clauses) {
10908       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10909         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10910                                      B.NumIterations, *this, CurScope,
10911                                      DSAStack))
10912           return StmtError();
10913     }
10914   }
10915 
10916   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10917   // The grainsize clause and num_tasks clause are mutually exclusive and may
10918   // not appear on the same taskloop directive.
10919   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10920     return StmtError();
10921   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10922   // If a reduction clause is present on the taskloop directive, the nogroup
10923   // clause must not be specified.
10924   if (checkReductionClauseWithNogroup(*this, Clauses))
10925     return StmtError();
10926   if (checkSimdlenSafelenSpecified(*this, Clauses))
10927     return StmtError();
10928 
10929   setFunctionHasBranchProtectedScope();
10930   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10931                                           NestedLoopCount, Clauses, AStmt, B);
10932 }
10933 
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10934 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10935     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10936     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10937   if (!AStmt)
10938     return StmtError();
10939 
10940   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10941   OMPLoopDirective::HelperExprs B;
10942   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10943   // define the nested loops number.
10944   unsigned NestedLoopCount =
10945       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10946                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10947                       VarsWithImplicitDSA, B);
10948   if (NestedLoopCount == 0)
10949     return StmtError();
10950 
10951   assert((CurContext->isDependentContext() || B.builtAll()) &&
10952          "omp for loop exprs were not built");
10953 
10954   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10955   // The grainsize clause and num_tasks clause are mutually exclusive and may
10956   // not appear on the same taskloop directive.
10957   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10958     return StmtError();
10959   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10960   // If a reduction clause is present on the taskloop directive, the nogroup
10961   // clause must not be specified.
10962   if (checkReductionClauseWithNogroup(*this, Clauses))
10963     return StmtError();
10964 
10965   setFunctionHasBranchProtectedScope();
10966   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10967                                             NestedLoopCount, Clauses, AStmt, B,
10968                                             DSAStack->isCancelRegion());
10969 }
10970 
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10971 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10972     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10973     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10974   if (!AStmt)
10975     return StmtError();
10976 
10977   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10978   OMPLoopDirective::HelperExprs B;
10979   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10980   // define the nested loops number.
10981   unsigned NestedLoopCount =
10982       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10983                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10984                       VarsWithImplicitDSA, B);
10985   if (NestedLoopCount == 0)
10986     return StmtError();
10987 
10988   assert((CurContext->isDependentContext() || B.builtAll()) &&
10989          "omp for loop exprs were not built");
10990 
10991   if (!CurContext->isDependentContext()) {
10992     // Finalize the clauses that need pre-built expressions for CodeGen.
10993     for (OMPClause *C : Clauses) {
10994       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10995         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10996                                      B.NumIterations, *this, CurScope,
10997                                      DSAStack))
10998           return StmtError();
10999     }
11000   }
11001 
11002   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11003   // The grainsize clause and num_tasks clause are mutually exclusive and may
11004   // not appear on the same taskloop directive.
11005   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11006     return StmtError();
11007   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11008   // If a reduction clause is present on the taskloop directive, the nogroup
11009   // clause must not be specified.
11010   if (checkReductionClauseWithNogroup(*this, Clauses))
11011     return StmtError();
11012   if (checkSimdlenSafelenSpecified(*this, Clauses))
11013     return StmtError();
11014 
11015   setFunctionHasBranchProtectedScope();
11016   return OMPMasterTaskLoopSimdDirective::Create(
11017       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11018 }
11019 
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11020 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11021     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11022     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11023   if (!AStmt)
11024     return StmtError();
11025 
11026   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11027   auto *CS = cast<CapturedStmt>(AStmt);
11028   // 1.2.2 OpenMP Language Terminology
11029   // Structured block - An executable statement with a single entry at the
11030   // top and a single exit at the bottom.
11031   // The point of exit cannot be a branch out of the structured block.
11032   // longjmp() and throw() must not violate the entry/exit criteria.
11033   CS->getCapturedDecl()->setNothrow();
11034   for (int ThisCaptureLevel =
11035            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11036        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11037     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11038     // 1.2.2 OpenMP Language Terminology
11039     // Structured block - An executable statement with a single entry at the
11040     // top and a single exit at the bottom.
11041     // The point of exit cannot be a branch out of the structured block.
11042     // longjmp() and throw() must not violate the entry/exit criteria.
11043     CS->getCapturedDecl()->setNothrow();
11044   }
11045 
11046   OMPLoopDirective::HelperExprs B;
11047   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11048   // define the nested loops number.
11049   unsigned NestedLoopCount = checkOpenMPLoop(
11050       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11051       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11052       VarsWithImplicitDSA, B);
11053   if (NestedLoopCount == 0)
11054     return StmtError();
11055 
11056   assert((CurContext->isDependentContext() || B.builtAll()) &&
11057          "omp for loop exprs were not built");
11058 
11059   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11060   // The grainsize clause and num_tasks clause are mutually exclusive and may
11061   // not appear on the same taskloop directive.
11062   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11063     return StmtError();
11064   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11065   // If a reduction clause is present on the taskloop directive, the nogroup
11066   // clause must not be specified.
11067   if (checkReductionClauseWithNogroup(*this, Clauses))
11068     return StmtError();
11069 
11070   setFunctionHasBranchProtectedScope();
11071   return OMPParallelMasterTaskLoopDirective::Create(
11072       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11073       DSAStack->isCancelRegion());
11074 }
11075 
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11076 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11077     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11078     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11079   if (!AStmt)
11080     return StmtError();
11081 
11082   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11083   auto *CS = cast<CapturedStmt>(AStmt);
11084   // 1.2.2 OpenMP Language Terminology
11085   // Structured block - An executable statement with a single entry at the
11086   // top and a single exit at the bottom.
11087   // The point of exit cannot be a branch out of the structured block.
11088   // longjmp() and throw() must not violate the entry/exit criteria.
11089   CS->getCapturedDecl()->setNothrow();
11090   for (int ThisCaptureLevel =
11091            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11092        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11093     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11094     // 1.2.2 OpenMP Language Terminology
11095     // Structured block - An executable statement with a single entry at the
11096     // top and a single exit at the bottom.
11097     // The point of exit cannot be a branch out of the structured block.
11098     // longjmp() and throw() must not violate the entry/exit criteria.
11099     CS->getCapturedDecl()->setNothrow();
11100   }
11101 
11102   OMPLoopDirective::HelperExprs B;
11103   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11104   // define the nested loops number.
11105   unsigned NestedLoopCount = checkOpenMPLoop(
11106       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11107       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11108       VarsWithImplicitDSA, B);
11109   if (NestedLoopCount == 0)
11110     return StmtError();
11111 
11112   assert((CurContext->isDependentContext() || B.builtAll()) &&
11113          "omp for loop exprs were not built");
11114 
11115   if (!CurContext->isDependentContext()) {
11116     // Finalize the clauses that need pre-built expressions for CodeGen.
11117     for (OMPClause *C : Clauses) {
11118       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11119         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11120                                      B.NumIterations, *this, CurScope,
11121                                      DSAStack))
11122           return StmtError();
11123     }
11124   }
11125 
11126   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11127   // The grainsize clause and num_tasks clause are mutually exclusive and may
11128   // not appear on the same taskloop directive.
11129   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11130     return StmtError();
11131   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11132   // If a reduction clause is present on the taskloop directive, the nogroup
11133   // clause must not be specified.
11134   if (checkReductionClauseWithNogroup(*this, Clauses))
11135     return StmtError();
11136   if (checkSimdlenSafelenSpecified(*this, Clauses))
11137     return StmtError();
11138 
11139   setFunctionHasBranchProtectedScope();
11140   return OMPParallelMasterTaskLoopSimdDirective::Create(
11141       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11142 }
11143 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11144 StmtResult Sema::ActOnOpenMPDistributeDirective(
11145     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11146     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11147   if (!AStmt)
11148     return StmtError();
11149 
11150   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11151   OMPLoopDirective::HelperExprs B;
11152   // In presence of clause 'collapse' with number of loops, it will
11153   // define the nested loops number.
11154   unsigned NestedLoopCount =
11155       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11156                       nullptr /*ordered not a clause on distribute*/, AStmt,
11157                       *this, *DSAStack, VarsWithImplicitDSA, B);
11158   if (NestedLoopCount == 0)
11159     return StmtError();
11160 
11161   assert((CurContext->isDependentContext() || B.builtAll()) &&
11162          "omp for loop exprs were not built");
11163 
11164   setFunctionHasBranchProtectedScope();
11165   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11166                                         NestedLoopCount, Clauses, AStmt, B);
11167 }
11168 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11169 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11170     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11171     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11172   if (!AStmt)
11173     return StmtError();
11174 
11175   auto *CS = cast<CapturedStmt>(AStmt);
11176   // 1.2.2 OpenMP Language Terminology
11177   // Structured block - An executable statement with a single entry at the
11178   // top and a single exit at the bottom.
11179   // The point of exit cannot be a branch out of the structured block.
11180   // longjmp() and throw() must not violate the entry/exit criteria.
11181   CS->getCapturedDecl()->setNothrow();
11182   for (int ThisCaptureLevel =
11183            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11184        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11185     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11186     // 1.2.2 OpenMP Language Terminology
11187     // Structured block - An executable statement with a single entry at the
11188     // top and a single exit at the bottom.
11189     // The point of exit cannot be a branch out of the structured block.
11190     // longjmp() and throw() must not violate the entry/exit criteria.
11191     CS->getCapturedDecl()->setNothrow();
11192   }
11193 
11194   OMPLoopDirective::HelperExprs B;
11195   // In presence of clause 'collapse' with number of loops, it will
11196   // define the nested loops number.
11197   unsigned NestedLoopCount = checkOpenMPLoop(
11198       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11199       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11200       VarsWithImplicitDSA, B);
11201   if (NestedLoopCount == 0)
11202     return StmtError();
11203 
11204   assert((CurContext->isDependentContext() || B.builtAll()) &&
11205          "omp for loop exprs were not built");
11206 
11207   setFunctionHasBranchProtectedScope();
11208   return OMPDistributeParallelForDirective::Create(
11209       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11210       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11211 }
11212 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11213 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11214     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11215     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11216   if (!AStmt)
11217     return StmtError();
11218 
11219   auto *CS = cast<CapturedStmt>(AStmt);
11220   // 1.2.2 OpenMP Language Terminology
11221   // Structured block - An executable statement with a single entry at the
11222   // top and a single exit at the bottom.
11223   // The point of exit cannot be a branch out of the structured block.
11224   // longjmp() and throw() must not violate the entry/exit criteria.
11225   CS->getCapturedDecl()->setNothrow();
11226   for (int ThisCaptureLevel =
11227            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11228        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11229     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11230     // 1.2.2 OpenMP Language Terminology
11231     // Structured block - An executable statement with a single entry at the
11232     // top and a single exit at the bottom.
11233     // The point of exit cannot be a branch out of the structured block.
11234     // longjmp() and throw() must not violate the entry/exit criteria.
11235     CS->getCapturedDecl()->setNothrow();
11236   }
11237 
11238   OMPLoopDirective::HelperExprs B;
11239   // In presence of clause 'collapse' with number of loops, it will
11240   // define the nested loops number.
11241   unsigned NestedLoopCount = checkOpenMPLoop(
11242       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11243       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11244       VarsWithImplicitDSA, B);
11245   if (NestedLoopCount == 0)
11246     return StmtError();
11247 
11248   assert((CurContext->isDependentContext() || B.builtAll()) &&
11249          "omp for loop exprs were not built");
11250 
11251   if (!CurContext->isDependentContext()) {
11252     // Finalize the clauses that need pre-built expressions for CodeGen.
11253     for (OMPClause *C : Clauses) {
11254       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11255         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11256                                      B.NumIterations, *this, CurScope,
11257                                      DSAStack))
11258           return StmtError();
11259     }
11260   }
11261 
11262   if (checkSimdlenSafelenSpecified(*this, Clauses))
11263     return StmtError();
11264 
11265   setFunctionHasBranchProtectedScope();
11266   return OMPDistributeParallelForSimdDirective::Create(
11267       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11268 }
11269 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11270 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11271     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11272     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11273   if (!AStmt)
11274     return StmtError();
11275 
11276   auto *CS = cast<CapturedStmt>(AStmt);
11277   // 1.2.2 OpenMP Language Terminology
11278   // Structured block - An executable statement with a single entry at the
11279   // top and a single exit at the bottom.
11280   // The point of exit cannot be a branch out of the structured block.
11281   // longjmp() and throw() must not violate the entry/exit criteria.
11282   CS->getCapturedDecl()->setNothrow();
11283   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11284        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11285     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11286     // 1.2.2 OpenMP Language Terminology
11287     // Structured block - An executable statement with a single entry at the
11288     // top and a single exit at the bottom.
11289     // The point of exit cannot be a branch out of the structured block.
11290     // longjmp() and throw() must not violate the entry/exit criteria.
11291     CS->getCapturedDecl()->setNothrow();
11292   }
11293 
11294   OMPLoopDirective::HelperExprs B;
11295   // In presence of clause 'collapse' with number of loops, it will
11296   // define the nested loops number.
11297   unsigned NestedLoopCount =
11298       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11299                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11300                       *DSAStack, VarsWithImplicitDSA, B);
11301   if (NestedLoopCount == 0)
11302     return StmtError();
11303 
11304   assert((CurContext->isDependentContext() || B.builtAll()) &&
11305          "omp for loop exprs were not built");
11306 
11307   if (!CurContext->isDependentContext()) {
11308     // Finalize the clauses that need pre-built expressions for CodeGen.
11309     for (OMPClause *C : Clauses) {
11310       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11311         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11312                                      B.NumIterations, *this, CurScope,
11313                                      DSAStack))
11314           return StmtError();
11315     }
11316   }
11317 
11318   if (checkSimdlenSafelenSpecified(*this, Clauses))
11319     return StmtError();
11320 
11321   setFunctionHasBranchProtectedScope();
11322   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11323                                             NestedLoopCount, Clauses, AStmt, B);
11324 }
11325 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11326 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11327     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11328     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11329   if (!AStmt)
11330     return StmtError();
11331 
11332   auto *CS = cast<CapturedStmt>(AStmt);
11333   // 1.2.2 OpenMP Language Terminology
11334   // Structured block - An executable statement with a single entry at the
11335   // top and a single exit at the bottom.
11336   // The point of exit cannot be a branch out of the structured block.
11337   // longjmp() and throw() must not violate the entry/exit criteria.
11338   CS->getCapturedDecl()->setNothrow();
11339   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11340        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11341     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11342     // 1.2.2 OpenMP Language Terminology
11343     // Structured block - An executable statement with a single entry at the
11344     // top and a single exit at the bottom.
11345     // The point of exit cannot be a branch out of the structured block.
11346     // longjmp() and throw() must not violate the entry/exit criteria.
11347     CS->getCapturedDecl()->setNothrow();
11348   }
11349 
11350   OMPLoopDirective::HelperExprs B;
11351   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11352   // define the nested loops number.
11353   unsigned NestedLoopCount = checkOpenMPLoop(
11354       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11355       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11356       VarsWithImplicitDSA, B);
11357   if (NestedLoopCount == 0)
11358     return StmtError();
11359 
11360   assert((CurContext->isDependentContext() || B.builtAll()) &&
11361          "omp target parallel for simd loop exprs were not built");
11362 
11363   if (!CurContext->isDependentContext()) {
11364     // Finalize the clauses that need pre-built expressions for CodeGen.
11365     for (OMPClause *C : Clauses) {
11366       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11367         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11368                                      B.NumIterations, *this, CurScope,
11369                                      DSAStack))
11370           return StmtError();
11371     }
11372   }
11373   if (checkSimdlenSafelenSpecified(*this, Clauses))
11374     return StmtError();
11375 
11376   setFunctionHasBranchProtectedScope();
11377   return OMPTargetParallelForSimdDirective::Create(
11378       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11379 }
11380 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11381 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11382     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11383     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11384   if (!AStmt)
11385     return StmtError();
11386 
11387   auto *CS = cast<CapturedStmt>(AStmt);
11388   // 1.2.2 OpenMP Language Terminology
11389   // Structured block - An executable statement with a single entry at the
11390   // top and a single exit at the bottom.
11391   // The point of exit cannot be a branch out of the structured block.
11392   // longjmp() and throw() must not violate the entry/exit criteria.
11393   CS->getCapturedDecl()->setNothrow();
11394   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11395        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11396     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11397     // 1.2.2 OpenMP Language Terminology
11398     // Structured block - An executable statement with a single entry at the
11399     // top and a single exit at the bottom.
11400     // The point of exit cannot be a branch out of the structured block.
11401     // longjmp() and throw() must not violate the entry/exit criteria.
11402     CS->getCapturedDecl()->setNothrow();
11403   }
11404 
11405   OMPLoopDirective::HelperExprs B;
11406   // In presence of clause 'collapse' with number of loops, it will define the
11407   // nested loops number.
11408   unsigned NestedLoopCount =
11409       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11410                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11411                       VarsWithImplicitDSA, B);
11412   if (NestedLoopCount == 0)
11413     return StmtError();
11414 
11415   assert((CurContext->isDependentContext() || B.builtAll()) &&
11416          "omp target simd loop exprs were not built");
11417 
11418   if (!CurContext->isDependentContext()) {
11419     // Finalize the clauses that need pre-built expressions for CodeGen.
11420     for (OMPClause *C : Clauses) {
11421       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11422         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11423                                      B.NumIterations, *this, CurScope,
11424                                      DSAStack))
11425           return StmtError();
11426     }
11427   }
11428 
11429   if (checkSimdlenSafelenSpecified(*this, Clauses))
11430     return StmtError();
11431 
11432   setFunctionHasBranchProtectedScope();
11433   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11434                                         NestedLoopCount, Clauses, AStmt, B);
11435 }
11436 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11437 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11438     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11439     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11440   if (!AStmt)
11441     return StmtError();
11442 
11443   auto *CS = cast<CapturedStmt>(AStmt);
11444   // 1.2.2 OpenMP Language Terminology
11445   // Structured block - An executable statement with a single entry at the
11446   // top and a single exit at the bottom.
11447   // The point of exit cannot be a branch out of the structured block.
11448   // longjmp() and throw() must not violate the entry/exit criteria.
11449   CS->getCapturedDecl()->setNothrow();
11450   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11451        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11452     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11453     // 1.2.2 OpenMP Language Terminology
11454     // Structured block - An executable statement with a single entry at the
11455     // top and a single exit at the bottom.
11456     // The point of exit cannot be a branch out of the structured block.
11457     // longjmp() and throw() must not violate the entry/exit criteria.
11458     CS->getCapturedDecl()->setNothrow();
11459   }
11460 
11461   OMPLoopDirective::HelperExprs B;
11462   // In presence of clause 'collapse' with number of loops, it will
11463   // define the nested loops number.
11464   unsigned NestedLoopCount =
11465       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11466                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11467                       *DSAStack, VarsWithImplicitDSA, B);
11468   if (NestedLoopCount == 0)
11469     return StmtError();
11470 
11471   assert((CurContext->isDependentContext() || B.builtAll()) &&
11472          "omp teams distribute loop exprs were not built");
11473 
11474   setFunctionHasBranchProtectedScope();
11475 
11476   DSAStack->setParentTeamsRegionLoc(StartLoc);
11477 
11478   return OMPTeamsDistributeDirective::Create(
11479       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11480 }
11481 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11482 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11483     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11484     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11485   if (!AStmt)
11486     return StmtError();
11487 
11488   auto *CS = cast<CapturedStmt>(AStmt);
11489   // 1.2.2 OpenMP Language Terminology
11490   // Structured block - An executable statement with a single entry at the
11491   // top and a single exit at the bottom.
11492   // The point of exit cannot be a branch out of the structured block.
11493   // longjmp() and throw() must not violate the entry/exit criteria.
11494   CS->getCapturedDecl()->setNothrow();
11495   for (int ThisCaptureLevel =
11496            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11497        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11498     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11499     // 1.2.2 OpenMP Language Terminology
11500     // Structured block - An executable statement with a single entry at the
11501     // top and a single exit at the bottom.
11502     // The point of exit cannot be a branch out of the structured block.
11503     // longjmp() and throw() must not violate the entry/exit criteria.
11504     CS->getCapturedDecl()->setNothrow();
11505   }
11506 
11507   OMPLoopDirective::HelperExprs B;
11508   // In presence of clause 'collapse' with number of loops, it will
11509   // define the nested loops number.
11510   unsigned NestedLoopCount = checkOpenMPLoop(
11511       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11512       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11513       VarsWithImplicitDSA, B);
11514 
11515   if (NestedLoopCount == 0)
11516     return StmtError();
11517 
11518   assert((CurContext->isDependentContext() || B.builtAll()) &&
11519          "omp teams distribute simd loop exprs were not built");
11520 
11521   if (!CurContext->isDependentContext()) {
11522     // Finalize the clauses that need pre-built expressions for CodeGen.
11523     for (OMPClause *C : Clauses) {
11524       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11525         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11526                                      B.NumIterations, *this, CurScope,
11527                                      DSAStack))
11528           return StmtError();
11529     }
11530   }
11531 
11532   if (checkSimdlenSafelenSpecified(*this, Clauses))
11533     return StmtError();
11534 
11535   setFunctionHasBranchProtectedScope();
11536 
11537   DSAStack->setParentTeamsRegionLoc(StartLoc);
11538 
11539   return OMPTeamsDistributeSimdDirective::Create(
11540       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11541 }
11542 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11543 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11544     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11545     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11546   if (!AStmt)
11547     return StmtError();
11548 
11549   auto *CS = cast<CapturedStmt>(AStmt);
11550   // 1.2.2 OpenMP Language Terminology
11551   // Structured block - An executable statement with a single entry at the
11552   // top and a single exit at the bottom.
11553   // The point of exit cannot be a branch out of the structured block.
11554   // longjmp() and throw() must not violate the entry/exit criteria.
11555   CS->getCapturedDecl()->setNothrow();
11556 
11557   for (int ThisCaptureLevel =
11558            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11559        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11560     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11561     // 1.2.2 OpenMP Language Terminology
11562     // Structured block - An executable statement with a single entry at the
11563     // top and a single exit at the bottom.
11564     // The point of exit cannot be a branch out of the structured block.
11565     // longjmp() and throw() must not violate the entry/exit criteria.
11566     CS->getCapturedDecl()->setNothrow();
11567   }
11568 
11569   OMPLoopDirective::HelperExprs B;
11570   // In presence of clause 'collapse' with number of loops, it will
11571   // define the nested loops number.
11572   unsigned NestedLoopCount = checkOpenMPLoop(
11573       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11574       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11575       VarsWithImplicitDSA, B);
11576 
11577   if (NestedLoopCount == 0)
11578     return StmtError();
11579 
11580   assert((CurContext->isDependentContext() || B.builtAll()) &&
11581          "omp for loop exprs were not built");
11582 
11583   if (!CurContext->isDependentContext()) {
11584     // Finalize the clauses that need pre-built expressions for CodeGen.
11585     for (OMPClause *C : Clauses) {
11586       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11587         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11588                                      B.NumIterations, *this, CurScope,
11589                                      DSAStack))
11590           return StmtError();
11591     }
11592   }
11593 
11594   if (checkSimdlenSafelenSpecified(*this, Clauses))
11595     return StmtError();
11596 
11597   setFunctionHasBranchProtectedScope();
11598 
11599   DSAStack->setParentTeamsRegionLoc(StartLoc);
11600 
11601   return OMPTeamsDistributeParallelForSimdDirective::Create(
11602       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11603 }
11604 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11605 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11606     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11607     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11608   if (!AStmt)
11609     return StmtError();
11610 
11611   auto *CS = cast<CapturedStmt>(AStmt);
11612   // 1.2.2 OpenMP Language Terminology
11613   // Structured block - An executable statement with a single entry at the
11614   // top and a single exit at the bottom.
11615   // The point of exit cannot be a branch out of the structured block.
11616   // longjmp() and throw() must not violate the entry/exit criteria.
11617   CS->getCapturedDecl()->setNothrow();
11618 
11619   for (int ThisCaptureLevel =
11620            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11621        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11622     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11623     // 1.2.2 OpenMP Language Terminology
11624     // Structured block - An executable statement with a single entry at the
11625     // top and a single exit at the bottom.
11626     // The point of exit cannot be a branch out of the structured block.
11627     // longjmp() and throw() must not violate the entry/exit criteria.
11628     CS->getCapturedDecl()->setNothrow();
11629   }
11630 
11631   OMPLoopDirective::HelperExprs B;
11632   // In presence of clause 'collapse' with number of loops, it will
11633   // define the nested loops number.
11634   unsigned NestedLoopCount = checkOpenMPLoop(
11635       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11636       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11637       VarsWithImplicitDSA, B);
11638 
11639   if (NestedLoopCount == 0)
11640     return StmtError();
11641 
11642   assert((CurContext->isDependentContext() || B.builtAll()) &&
11643          "omp for loop exprs were not built");
11644 
11645   setFunctionHasBranchProtectedScope();
11646 
11647   DSAStack->setParentTeamsRegionLoc(StartLoc);
11648 
11649   return OMPTeamsDistributeParallelForDirective::Create(
11650       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11651       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11652 }
11653 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11654 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11655                                                  Stmt *AStmt,
11656                                                  SourceLocation StartLoc,
11657                                                  SourceLocation EndLoc) {
11658   if (!AStmt)
11659     return StmtError();
11660 
11661   auto *CS = cast<CapturedStmt>(AStmt);
11662   // 1.2.2 OpenMP Language Terminology
11663   // Structured block - An executable statement with a single entry at the
11664   // top and a single exit at the bottom.
11665   // The point of exit cannot be a branch out of the structured block.
11666   // longjmp() and throw() must not violate the entry/exit criteria.
11667   CS->getCapturedDecl()->setNothrow();
11668 
11669   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11670        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11671     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11672     // 1.2.2 OpenMP Language Terminology
11673     // Structured block - An executable statement with a single entry at the
11674     // top and a single exit at the bottom.
11675     // The point of exit cannot be a branch out of the structured block.
11676     // longjmp() and throw() must not violate the entry/exit criteria.
11677     CS->getCapturedDecl()->setNothrow();
11678   }
11679   setFunctionHasBranchProtectedScope();
11680 
11681   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11682                                          AStmt);
11683 }
11684 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11685 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11686     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11687     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11688   if (!AStmt)
11689     return StmtError();
11690 
11691   auto *CS = cast<CapturedStmt>(AStmt);
11692   // 1.2.2 OpenMP Language Terminology
11693   // Structured block - An executable statement with a single entry at the
11694   // top and a single exit at the bottom.
11695   // The point of exit cannot be a branch out of the structured block.
11696   // longjmp() and throw() must not violate the entry/exit criteria.
11697   CS->getCapturedDecl()->setNothrow();
11698   for (int ThisCaptureLevel =
11699            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11700        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11701     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11702     // 1.2.2 OpenMP Language Terminology
11703     // Structured block - An executable statement with a single entry at the
11704     // top and a single exit at the bottom.
11705     // The point of exit cannot be a branch out of the structured block.
11706     // longjmp() and throw() must not violate the entry/exit criteria.
11707     CS->getCapturedDecl()->setNothrow();
11708   }
11709 
11710   OMPLoopDirective::HelperExprs B;
11711   // In presence of clause 'collapse' with number of loops, it will
11712   // define the nested loops number.
11713   unsigned NestedLoopCount = checkOpenMPLoop(
11714       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11715       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11716       VarsWithImplicitDSA, B);
11717   if (NestedLoopCount == 0)
11718     return StmtError();
11719 
11720   assert((CurContext->isDependentContext() || B.builtAll()) &&
11721          "omp target teams distribute loop exprs were not built");
11722 
11723   setFunctionHasBranchProtectedScope();
11724   return OMPTargetTeamsDistributeDirective::Create(
11725       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11726 }
11727 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11728 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11729     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11730     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11731   if (!AStmt)
11732     return StmtError();
11733 
11734   auto *CS = cast<CapturedStmt>(AStmt);
11735   // 1.2.2 OpenMP Language Terminology
11736   // Structured block - An executable statement with a single entry at the
11737   // top and a single exit at the bottom.
11738   // The point of exit cannot be a branch out of the structured block.
11739   // longjmp() and throw() must not violate the entry/exit criteria.
11740   CS->getCapturedDecl()->setNothrow();
11741   for (int ThisCaptureLevel =
11742            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11743        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11744     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11745     // 1.2.2 OpenMP Language Terminology
11746     // Structured block - An executable statement with a single entry at the
11747     // top and a single exit at the bottom.
11748     // The point of exit cannot be a branch out of the structured block.
11749     // longjmp() and throw() must not violate the entry/exit criteria.
11750     CS->getCapturedDecl()->setNothrow();
11751   }
11752 
11753   OMPLoopDirective::HelperExprs B;
11754   // In presence of clause 'collapse' with number of loops, it will
11755   // define the nested loops number.
11756   unsigned NestedLoopCount = checkOpenMPLoop(
11757       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11758       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11759       VarsWithImplicitDSA, B);
11760   if (NestedLoopCount == 0)
11761     return StmtError();
11762 
11763   assert((CurContext->isDependentContext() || B.builtAll()) &&
11764          "omp target teams distribute parallel for loop exprs were not built");
11765 
11766   if (!CurContext->isDependentContext()) {
11767     // Finalize the clauses that need pre-built expressions for CodeGen.
11768     for (OMPClause *C : Clauses) {
11769       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11770         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11771                                      B.NumIterations, *this, CurScope,
11772                                      DSAStack))
11773           return StmtError();
11774     }
11775   }
11776 
11777   setFunctionHasBranchProtectedScope();
11778   return OMPTargetTeamsDistributeParallelForDirective::Create(
11779       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11780       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11781 }
11782 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11783 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11784     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11785     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11786   if (!AStmt)
11787     return StmtError();
11788 
11789   auto *CS = cast<CapturedStmt>(AStmt);
11790   // 1.2.2 OpenMP Language Terminology
11791   // Structured block - An executable statement with a single entry at the
11792   // top and a single exit at the bottom.
11793   // The point of exit cannot be a branch out of the structured block.
11794   // longjmp() and throw() must not violate the entry/exit criteria.
11795   CS->getCapturedDecl()->setNothrow();
11796   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11797            OMPD_target_teams_distribute_parallel_for_simd);
11798        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11799     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11800     // 1.2.2 OpenMP Language Terminology
11801     // Structured block - An executable statement with a single entry at the
11802     // top and a single exit at the bottom.
11803     // The point of exit cannot be a branch out of the structured block.
11804     // longjmp() and throw() must not violate the entry/exit criteria.
11805     CS->getCapturedDecl()->setNothrow();
11806   }
11807 
11808   OMPLoopDirective::HelperExprs B;
11809   // In presence of clause 'collapse' with number of loops, it will
11810   // define the nested loops number.
11811   unsigned NestedLoopCount =
11812       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11813                       getCollapseNumberExpr(Clauses),
11814                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11815                       *DSAStack, VarsWithImplicitDSA, B);
11816   if (NestedLoopCount == 0)
11817     return StmtError();
11818 
11819   assert((CurContext->isDependentContext() || B.builtAll()) &&
11820          "omp target teams distribute parallel for simd loop exprs were not "
11821          "built");
11822 
11823   if (!CurContext->isDependentContext()) {
11824     // Finalize the clauses that need pre-built expressions for CodeGen.
11825     for (OMPClause *C : Clauses) {
11826       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11827         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11828                                      B.NumIterations, *this, CurScope,
11829                                      DSAStack))
11830           return StmtError();
11831     }
11832   }
11833 
11834   if (checkSimdlenSafelenSpecified(*this, Clauses))
11835     return StmtError();
11836 
11837   setFunctionHasBranchProtectedScope();
11838   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11839       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11840 }
11841 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11842 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11843     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11844     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11845   if (!AStmt)
11846     return StmtError();
11847 
11848   auto *CS = cast<CapturedStmt>(AStmt);
11849   // 1.2.2 OpenMP Language Terminology
11850   // Structured block - An executable statement with a single entry at the
11851   // top and a single exit at the bottom.
11852   // The point of exit cannot be a branch out of the structured block.
11853   // longjmp() and throw() must not violate the entry/exit criteria.
11854   CS->getCapturedDecl()->setNothrow();
11855   for (int ThisCaptureLevel =
11856            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11857        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11858     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11859     // 1.2.2 OpenMP Language Terminology
11860     // Structured block - An executable statement with a single entry at the
11861     // top and a single exit at the bottom.
11862     // The point of exit cannot be a branch out of the structured block.
11863     // longjmp() and throw() must not violate the entry/exit criteria.
11864     CS->getCapturedDecl()->setNothrow();
11865   }
11866 
11867   OMPLoopDirective::HelperExprs B;
11868   // In presence of clause 'collapse' with number of loops, it will
11869   // define the nested loops number.
11870   unsigned NestedLoopCount = checkOpenMPLoop(
11871       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11872       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11873       VarsWithImplicitDSA, B);
11874   if (NestedLoopCount == 0)
11875     return StmtError();
11876 
11877   assert((CurContext->isDependentContext() || B.builtAll()) &&
11878          "omp target teams distribute simd loop exprs were not built");
11879 
11880   if (!CurContext->isDependentContext()) {
11881     // Finalize the clauses that need pre-built expressions for CodeGen.
11882     for (OMPClause *C : Clauses) {
11883       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11884         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11885                                      B.NumIterations, *this, CurScope,
11886                                      DSAStack))
11887           return StmtError();
11888     }
11889   }
11890 
11891   if (checkSimdlenSafelenSpecified(*this, Clauses))
11892     return StmtError();
11893 
11894   setFunctionHasBranchProtectedScope();
11895   return OMPTargetTeamsDistributeSimdDirective::Create(
11896       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11897 }
11898 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11899 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11900                                              SourceLocation StartLoc,
11901                                              SourceLocation LParenLoc,
11902                                              SourceLocation EndLoc) {
11903   OMPClause *Res = nullptr;
11904   switch (Kind) {
11905   case OMPC_final:
11906     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11907     break;
11908   case OMPC_num_threads:
11909     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11910     break;
11911   case OMPC_safelen:
11912     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11913     break;
11914   case OMPC_simdlen:
11915     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11916     break;
11917   case OMPC_allocator:
11918     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11919     break;
11920   case OMPC_collapse:
11921     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11922     break;
11923   case OMPC_ordered:
11924     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11925     break;
11926   case OMPC_num_teams:
11927     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11928     break;
11929   case OMPC_thread_limit:
11930     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11931     break;
11932   case OMPC_priority:
11933     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11934     break;
11935   case OMPC_grainsize:
11936     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11937     break;
11938   case OMPC_num_tasks:
11939     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11940     break;
11941   case OMPC_hint:
11942     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11943     break;
11944   case OMPC_depobj:
11945     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11946     break;
11947   case OMPC_detach:
11948     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11949     break;
11950   case OMPC_device:
11951   case OMPC_if:
11952   case OMPC_default:
11953   case OMPC_proc_bind:
11954   case OMPC_schedule:
11955   case OMPC_private:
11956   case OMPC_firstprivate:
11957   case OMPC_lastprivate:
11958   case OMPC_shared:
11959   case OMPC_reduction:
11960   case OMPC_task_reduction:
11961   case OMPC_in_reduction:
11962   case OMPC_linear:
11963   case OMPC_aligned:
11964   case OMPC_copyin:
11965   case OMPC_copyprivate:
11966   case OMPC_nowait:
11967   case OMPC_untied:
11968   case OMPC_mergeable:
11969   case OMPC_threadprivate:
11970   case OMPC_allocate:
11971   case OMPC_flush:
11972   case OMPC_read:
11973   case OMPC_write:
11974   case OMPC_update:
11975   case OMPC_capture:
11976   case OMPC_seq_cst:
11977   case OMPC_acq_rel:
11978   case OMPC_acquire:
11979   case OMPC_release:
11980   case OMPC_relaxed:
11981   case OMPC_depend:
11982   case OMPC_threads:
11983   case OMPC_simd:
11984   case OMPC_map:
11985   case OMPC_nogroup:
11986   case OMPC_dist_schedule:
11987   case OMPC_defaultmap:
11988   case OMPC_unknown:
11989   case OMPC_uniform:
11990   case OMPC_to:
11991   case OMPC_from:
11992   case OMPC_use_device_ptr:
11993   case OMPC_use_device_addr:
11994   case OMPC_is_device_ptr:
11995   case OMPC_unified_address:
11996   case OMPC_unified_shared_memory:
11997   case OMPC_reverse_offload:
11998   case OMPC_dynamic_allocators:
11999   case OMPC_atomic_default_mem_order:
12000   case OMPC_device_type:
12001   case OMPC_match:
12002   case OMPC_nontemporal:
12003   case OMPC_order:
12004   case OMPC_destroy:
12005   case OMPC_inclusive:
12006   case OMPC_exclusive:
12007   case OMPC_uses_allocators:
12008   case OMPC_affinity:
12009   default:
12010     llvm_unreachable("Clause is not allowed.");
12011   }
12012   return Res;
12013 }
12014 
12015 // An OpenMP directive such as 'target parallel' has two captured regions:
12016 // for the 'target' and 'parallel' respectively.  This function returns
12017 // the region in which to capture expressions associated with a clause.
12018 // A return value of OMPD_unknown signifies that the expression should not
12019 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)12020 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12021     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12022     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12023   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12024   switch (CKind) {
12025   case OMPC_if:
12026     switch (DKind) {
12027     case OMPD_target_parallel_for_simd:
12028       if (OpenMPVersion >= 50 &&
12029           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12030         CaptureRegion = OMPD_parallel;
12031         break;
12032       }
12033       LLVM_FALLTHROUGH;
12034     case OMPD_target_parallel:
12035     case OMPD_target_parallel_for:
12036       // If this clause applies to the nested 'parallel' region, capture within
12037       // the 'target' region, otherwise do not capture.
12038       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12039         CaptureRegion = OMPD_target;
12040       break;
12041     case OMPD_target_teams_distribute_parallel_for_simd:
12042       if (OpenMPVersion >= 50 &&
12043           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12044         CaptureRegion = OMPD_parallel;
12045         break;
12046       }
12047       LLVM_FALLTHROUGH;
12048     case OMPD_target_teams_distribute_parallel_for:
12049       // If this clause applies to the nested 'parallel' region, capture within
12050       // the 'teams' region, otherwise do not capture.
12051       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12052         CaptureRegion = OMPD_teams;
12053       break;
12054     case OMPD_teams_distribute_parallel_for_simd:
12055       if (OpenMPVersion >= 50 &&
12056           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12057         CaptureRegion = OMPD_parallel;
12058         break;
12059       }
12060       LLVM_FALLTHROUGH;
12061     case OMPD_teams_distribute_parallel_for:
12062       CaptureRegion = OMPD_teams;
12063       break;
12064     case OMPD_target_update:
12065     case OMPD_target_enter_data:
12066     case OMPD_target_exit_data:
12067       CaptureRegion = OMPD_task;
12068       break;
12069     case OMPD_parallel_master_taskloop:
12070       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12071         CaptureRegion = OMPD_parallel;
12072       break;
12073     case OMPD_parallel_master_taskloop_simd:
12074       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12075           NameModifier == OMPD_taskloop) {
12076         CaptureRegion = OMPD_parallel;
12077         break;
12078       }
12079       if (OpenMPVersion <= 45)
12080         break;
12081       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12082         CaptureRegion = OMPD_taskloop;
12083       break;
12084     case OMPD_parallel_for_simd:
12085       if (OpenMPVersion <= 45)
12086         break;
12087       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12088         CaptureRegion = OMPD_parallel;
12089       break;
12090     case OMPD_taskloop_simd:
12091     case OMPD_master_taskloop_simd:
12092       if (OpenMPVersion <= 45)
12093         break;
12094       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12095         CaptureRegion = OMPD_taskloop;
12096       break;
12097     case OMPD_distribute_parallel_for_simd:
12098       if (OpenMPVersion <= 45)
12099         break;
12100       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12101         CaptureRegion = OMPD_parallel;
12102       break;
12103     case OMPD_target_simd:
12104       if (OpenMPVersion >= 50 &&
12105           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12106         CaptureRegion = OMPD_target;
12107       break;
12108     case OMPD_teams_distribute_simd:
12109     case OMPD_target_teams_distribute_simd:
12110       if (OpenMPVersion >= 50 &&
12111           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12112         CaptureRegion = OMPD_teams;
12113       break;
12114     case OMPD_cancel:
12115     case OMPD_parallel:
12116     case OMPD_parallel_master:
12117     case OMPD_parallel_sections:
12118     case OMPD_parallel_for:
12119     case OMPD_target:
12120     case OMPD_target_teams:
12121     case OMPD_target_teams_distribute:
12122     case OMPD_distribute_parallel_for:
12123     case OMPD_task:
12124     case OMPD_taskloop:
12125     case OMPD_master_taskloop:
12126     case OMPD_target_data:
12127     case OMPD_simd:
12128     case OMPD_for_simd:
12129     case OMPD_distribute_simd:
12130       // Do not capture if-clause expressions.
12131       break;
12132     case OMPD_threadprivate:
12133     case OMPD_allocate:
12134     case OMPD_taskyield:
12135     case OMPD_barrier:
12136     case OMPD_taskwait:
12137     case OMPD_cancellation_point:
12138     case OMPD_flush:
12139     case OMPD_depobj:
12140     case OMPD_scan:
12141     case OMPD_declare_reduction:
12142     case OMPD_declare_mapper:
12143     case OMPD_declare_simd:
12144     case OMPD_declare_variant:
12145     case OMPD_begin_declare_variant:
12146     case OMPD_end_declare_variant:
12147     case OMPD_declare_target:
12148     case OMPD_end_declare_target:
12149     case OMPD_teams:
12150     case OMPD_for:
12151     case OMPD_sections:
12152     case OMPD_section:
12153     case OMPD_single:
12154     case OMPD_master:
12155     case OMPD_critical:
12156     case OMPD_taskgroup:
12157     case OMPD_distribute:
12158     case OMPD_ordered:
12159     case OMPD_atomic:
12160     case OMPD_teams_distribute:
12161     case OMPD_requires:
12162       llvm_unreachable("Unexpected OpenMP directive with if-clause");
12163     case OMPD_unknown:
12164     default:
12165       llvm_unreachable("Unknown OpenMP directive");
12166     }
12167     break;
12168   case OMPC_num_threads:
12169     switch (DKind) {
12170     case OMPD_target_parallel:
12171     case OMPD_target_parallel_for:
12172     case OMPD_target_parallel_for_simd:
12173       CaptureRegion = OMPD_target;
12174       break;
12175     case OMPD_teams_distribute_parallel_for:
12176     case OMPD_teams_distribute_parallel_for_simd:
12177     case OMPD_target_teams_distribute_parallel_for:
12178     case OMPD_target_teams_distribute_parallel_for_simd:
12179       CaptureRegion = OMPD_teams;
12180       break;
12181     case OMPD_parallel:
12182     case OMPD_parallel_master:
12183     case OMPD_parallel_sections:
12184     case OMPD_parallel_for:
12185     case OMPD_parallel_for_simd:
12186     case OMPD_distribute_parallel_for:
12187     case OMPD_distribute_parallel_for_simd:
12188     case OMPD_parallel_master_taskloop:
12189     case OMPD_parallel_master_taskloop_simd:
12190       // Do not capture num_threads-clause expressions.
12191       break;
12192     case OMPD_target_data:
12193     case OMPD_target_enter_data:
12194     case OMPD_target_exit_data:
12195     case OMPD_target_update:
12196     case OMPD_target:
12197     case OMPD_target_simd:
12198     case OMPD_target_teams:
12199     case OMPD_target_teams_distribute:
12200     case OMPD_target_teams_distribute_simd:
12201     case OMPD_cancel:
12202     case OMPD_task:
12203     case OMPD_taskloop:
12204     case OMPD_taskloop_simd:
12205     case OMPD_master_taskloop:
12206     case OMPD_master_taskloop_simd:
12207     case OMPD_threadprivate:
12208     case OMPD_allocate:
12209     case OMPD_taskyield:
12210     case OMPD_barrier:
12211     case OMPD_taskwait:
12212     case OMPD_cancellation_point:
12213     case OMPD_flush:
12214     case OMPD_depobj:
12215     case OMPD_scan:
12216     case OMPD_declare_reduction:
12217     case OMPD_declare_mapper:
12218     case OMPD_declare_simd:
12219     case OMPD_declare_variant:
12220     case OMPD_begin_declare_variant:
12221     case OMPD_end_declare_variant:
12222     case OMPD_declare_target:
12223     case OMPD_end_declare_target:
12224     case OMPD_teams:
12225     case OMPD_simd:
12226     case OMPD_for:
12227     case OMPD_for_simd:
12228     case OMPD_sections:
12229     case OMPD_section:
12230     case OMPD_single:
12231     case OMPD_master:
12232     case OMPD_critical:
12233     case OMPD_taskgroup:
12234     case OMPD_distribute:
12235     case OMPD_ordered:
12236     case OMPD_atomic:
12237     case OMPD_distribute_simd:
12238     case OMPD_teams_distribute:
12239     case OMPD_teams_distribute_simd:
12240     case OMPD_requires:
12241       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
12242     case OMPD_unknown:
12243     default:
12244       llvm_unreachable("Unknown OpenMP directive");
12245     }
12246     break;
12247   case OMPC_num_teams:
12248     switch (DKind) {
12249     case OMPD_target_teams:
12250     case OMPD_target_teams_distribute:
12251     case OMPD_target_teams_distribute_simd:
12252     case OMPD_target_teams_distribute_parallel_for:
12253     case OMPD_target_teams_distribute_parallel_for_simd:
12254       CaptureRegion = OMPD_target;
12255       break;
12256     case OMPD_teams_distribute_parallel_for:
12257     case OMPD_teams_distribute_parallel_for_simd:
12258     case OMPD_teams:
12259     case OMPD_teams_distribute:
12260     case OMPD_teams_distribute_simd:
12261       // Do not capture num_teams-clause expressions.
12262       break;
12263     case OMPD_distribute_parallel_for:
12264     case OMPD_distribute_parallel_for_simd:
12265     case OMPD_task:
12266     case OMPD_taskloop:
12267     case OMPD_taskloop_simd:
12268     case OMPD_master_taskloop:
12269     case OMPD_master_taskloop_simd:
12270     case OMPD_parallel_master_taskloop:
12271     case OMPD_parallel_master_taskloop_simd:
12272     case OMPD_target_data:
12273     case OMPD_target_enter_data:
12274     case OMPD_target_exit_data:
12275     case OMPD_target_update:
12276     case OMPD_cancel:
12277     case OMPD_parallel:
12278     case OMPD_parallel_master:
12279     case OMPD_parallel_sections:
12280     case OMPD_parallel_for:
12281     case OMPD_parallel_for_simd:
12282     case OMPD_target:
12283     case OMPD_target_simd:
12284     case OMPD_target_parallel:
12285     case OMPD_target_parallel_for:
12286     case OMPD_target_parallel_for_simd:
12287     case OMPD_threadprivate:
12288     case OMPD_allocate:
12289     case OMPD_taskyield:
12290     case OMPD_barrier:
12291     case OMPD_taskwait:
12292     case OMPD_cancellation_point:
12293     case OMPD_flush:
12294     case OMPD_depobj:
12295     case OMPD_scan:
12296     case OMPD_declare_reduction:
12297     case OMPD_declare_mapper:
12298     case OMPD_declare_simd:
12299     case OMPD_declare_variant:
12300     case OMPD_begin_declare_variant:
12301     case OMPD_end_declare_variant:
12302     case OMPD_declare_target:
12303     case OMPD_end_declare_target:
12304     case OMPD_simd:
12305     case OMPD_for:
12306     case OMPD_for_simd:
12307     case OMPD_sections:
12308     case OMPD_section:
12309     case OMPD_single:
12310     case OMPD_master:
12311     case OMPD_critical:
12312     case OMPD_taskgroup:
12313     case OMPD_distribute:
12314     case OMPD_ordered:
12315     case OMPD_atomic:
12316     case OMPD_distribute_simd:
12317     case OMPD_requires:
12318       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12319     case OMPD_unknown:
12320     default:
12321       llvm_unreachable("Unknown OpenMP directive");
12322     }
12323     break;
12324   case OMPC_thread_limit:
12325     switch (DKind) {
12326     case OMPD_target_teams:
12327     case OMPD_target_teams_distribute:
12328     case OMPD_target_teams_distribute_simd:
12329     case OMPD_target_teams_distribute_parallel_for:
12330     case OMPD_target_teams_distribute_parallel_for_simd:
12331       CaptureRegion = OMPD_target;
12332       break;
12333     case OMPD_teams_distribute_parallel_for:
12334     case OMPD_teams_distribute_parallel_for_simd:
12335     case OMPD_teams:
12336     case OMPD_teams_distribute:
12337     case OMPD_teams_distribute_simd:
12338       // Do not capture thread_limit-clause expressions.
12339       break;
12340     case OMPD_distribute_parallel_for:
12341     case OMPD_distribute_parallel_for_simd:
12342     case OMPD_task:
12343     case OMPD_taskloop:
12344     case OMPD_taskloop_simd:
12345     case OMPD_master_taskloop:
12346     case OMPD_master_taskloop_simd:
12347     case OMPD_parallel_master_taskloop:
12348     case OMPD_parallel_master_taskloop_simd:
12349     case OMPD_target_data:
12350     case OMPD_target_enter_data:
12351     case OMPD_target_exit_data:
12352     case OMPD_target_update:
12353     case OMPD_cancel:
12354     case OMPD_parallel:
12355     case OMPD_parallel_master:
12356     case OMPD_parallel_sections:
12357     case OMPD_parallel_for:
12358     case OMPD_parallel_for_simd:
12359     case OMPD_target:
12360     case OMPD_target_simd:
12361     case OMPD_target_parallel:
12362     case OMPD_target_parallel_for:
12363     case OMPD_target_parallel_for_simd:
12364     case OMPD_threadprivate:
12365     case OMPD_allocate:
12366     case OMPD_taskyield:
12367     case OMPD_barrier:
12368     case OMPD_taskwait:
12369     case OMPD_cancellation_point:
12370     case OMPD_flush:
12371     case OMPD_depobj:
12372     case OMPD_scan:
12373     case OMPD_declare_reduction:
12374     case OMPD_declare_mapper:
12375     case OMPD_declare_simd:
12376     case OMPD_declare_variant:
12377     case OMPD_begin_declare_variant:
12378     case OMPD_end_declare_variant:
12379     case OMPD_declare_target:
12380     case OMPD_end_declare_target:
12381     case OMPD_simd:
12382     case OMPD_for:
12383     case OMPD_for_simd:
12384     case OMPD_sections:
12385     case OMPD_section:
12386     case OMPD_single:
12387     case OMPD_master:
12388     case OMPD_critical:
12389     case OMPD_taskgroup:
12390     case OMPD_distribute:
12391     case OMPD_ordered:
12392     case OMPD_atomic:
12393     case OMPD_distribute_simd:
12394     case OMPD_requires:
12395       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
12396     case OMPD_unknown:
12397     default:
12398       llvm_unreachable("Unknown OpenMP directive");
12399     }
12400     break;
12401   case OMPC_schedule:
12402     switch (DKind) {
12403     case OMPD_parallel_for:
12404     case OMPD_parallel_for_simd:
12405     case OMPD_distribute_parallel_for:
12406     case OMPD_distribute_parallel_for_simd:
12407     case OMPD_teams_distribute_parallel_for:
12408     case OMPD_teams_distribute_parallel_for_simd:
12409     case OMPD_target_parallel_for:
12410     case OMPD_target_parallel_for_simd:
12411     case OMPD_target_teams_distribute_parallel_for:
12412     case OMPD_target_teams_distribute_parallel_for_simd:
12413       CaptureRegion = OMPD_parallel;
12414       break;
12415     case OMPD_for:
12416     case OMPD_for_simd:
12417       // Do not capture schedule-clause expressions.
12418       break;
12419     case OMPD_task:
12420     case OMPD_taskloop:
12421     case OMPD_taskloop_simd:
12422     case OMPD_master_taskloop:
12423     case OMPD_master_taskloop_simd:
12424     case OMPD_parallel_master_taskloop:
12425     case OMPD_parallel_master_taskloop_simd:
12426     case OMPD_target_data:
12427     case OMPD_target_enter_data:
12428     case OMPD_target_exit_data:
12429     case OMPD_target_update:
12430     case OMPD_teams:
12431     case OMPD_teams_distribute:
12432     case OMPD_teams_distribute_simd:
12433     case OMPD_target_teams_distribute:
12434     case OMPD_target_teams_distribute_simd:
12435     case OMPD_target:
12436     case OMPD_target_simd:
12437     case OMPD_target_parallel:
12438     case OMPD_cancel:
12439     case OMPD_parallel:
12440     case OMPD_parallel_master:
12441     case OMPD_parallel_sections:
12442     case OMPD_threadprivate:
12443     case OMPD_allocate:
12444     case OMPD_taskyield:
12445     case OMPD_barrier:
12446     case OMPD_taskwait:
12447     case OMPD_cancellation_point:
12448     case OMPD_flush:
12449     case OMPD_depobj:
12450     case OMPD_scan:
12451     case OMPD_declare_reduction:
12452     case OMPD_declare_mapper:
12453     case OMPD_declare_simd:
12454     case OMPD_declare_variant:
12455     case OMPD_begin_declare_variant:
12456     case OMPD_end_declare_variant:
12457     case OMPD_declare_target:
12458     case OMPD_end_declare_target:
12459     case OMPD_simd:
12460     case OMPD_sections:
12461     case OMPD_section:
12462     case OMPD_single:
12463     case OMPD_master:
12464     case OMPD_critical:
12465     case OMPD_taskgroup:
12466     case OMPD_distribute:
12467     case OMPD_ordered:
12468     case OMPD_atomic:
12469     case OMPD_distribute_simd:
12470     case OMPD_target_teams:
12471     case OMPD_requires:
12472       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12473     case OMPD_unknown:
12474     default:
12475       llvm_unreachable("Unknown OpenMP directive");
12476     }
12477     break;
12478   case OMPC_dist_schedule:
12479     switch (DKind) {
12480     case OMPD_teams_distribute_parallel_for:
12481     case OMPD_teams_distribute_parallel_for_simd:
12482     case OMPD_teams_distribute:
12483     case OMPD_teams_distribute_simd:
12484     case OMPD_target_teams_distribute_parallel_for:
12485     case OMPD_target_teams_distribute_parallel_for_simd:
12486     case OMPD_target_teams_distribute:
12487     case OMPD_target_teams_distribute_simd:
12488       CaptureRegion = OMPD_teams;
12489       break;
12490     case OMPD_distribute_parallel_for:
12491     case OMPD_distribute_parallel_for_simd:
12492     case OMPD_distribute:
12493     case OMPD_distribute_simd:
12494       // Do not capture thread_limit-clause expressions.
12495       break;
12496     case OMPD_parallel_for:
12497     case OMPD_parallel_for_simd:
12498     case OMPD_target_parallel_for_simd:
12499     case OMPD_target_parallel_for:
12500     case OMPD_task:
12501     case OMPD_taskloop:
12502     case OMPD_taskloop_simd:
12503     case OMPD_master_taskloop:
12504     case OMPD_master_taskloop_simd:
12505     case OMPD_parallel_master_taskloop:
12506     case OMPD_parallel_master_taskloop_simd:
12507     case OMPD_target_data:
12508     case OMPD_target_enter_data:
12509     case OMPD_target_exit_data:
12510     case OMPD_target_update:
12511     case OMPD_teams:
12512     case OMPD_target:
12513     case OMPD_target_simd:
12514     case OMPD_target_parallel:
12515     case OMPD_cancel:
12516     case OMPD_parallel:
12517     case OMPD_parallel_master:
12518     case OMPD_parallel_sections:
12519     case OMPD_threadprivate:
12520     case OMPD_allocate:
12521     case OMPD_taskyield:
12522     case OMPD_barrier:
12523     case OMPD_taskwait:
12524     case OMPD_cancellation_point:
12525     case OMPD_flush:
12526     case OMPD_depobj:
12527     case OMPD_scan:
12528     case OMPD_declare_reduction:
12529     case OMPD_declare_mapper:
12530     case OMPD_declare_simd:
12531     case OMPD_declare_variant:
12532     case OMPD_begin_declare_variant:
12533     case OMPD_end_declare_variant:
12534     case OMPD_declare_target:
12535     case OMPD_end_declare_target:
12536     case OMPD_simd:
12537     case OMPD_for:
12538     case OMPD_for_simd:
12539     case OMPD_sections:
12540     case OMPD_section:
12541     case OMPD_single:
12542     case OMPD_master:
12543     case OMPD_critical:
12544     case OMPD_taskgroup:
12545     case OMPD_ordered:
12546     case OMPD_atomic:
12547     case OMPD_target_teams:
12548     case OMPD_requires:
12549       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12550     case OMPD_unknown:
12551     default:
12552       llvm_unreachable("Unknown OpenMP directive");
12553     }
12554     break;
12555   case OMPC_device:
12556     switch (DKind) {
12557     case OMPD_target_update:
12558     case OMPD_target_enter_data:
12559     case OMPD_target_exit_data:
12560     case OMPD_target:
12561     case OMPD_target_simd:
12562     case OMPD_target_teams:
12563     case OMPD_target_parallel:
12564     case OMPD_target_teams_distribute:
12565     case OMPD_target_teams_distribute_simd:
12566     case OMPD_target_parallel_for:
12567     case OMPD_target_parallel_for_simd:
12568     case OMPD_target_teams_distribute_parallel_for:
12569     case OMPD_target_teams_distribute_parallel_for_simd:
12570       CaptureRegion = OMPD_task;
12571       break;
12572     case OMPD_target_data:
12573       // Do not capture device-clause expressions.
12574       break;
12575     case OMPD_teams_distribute_parallel_for:
12576     case OMPD_teams_distribute_parallel_for_simd:
12577     case OMPD_teams:
12578     case OMPD_teams_distribute:
12579     case OMPD_teams_distribute_simd:
12580     case OMPD_distribute_parallel_for:
12581     case OMPD_distribute_parallel_for_simd:
12582     case OMPD_task:
12583     case OMPD_taskloop:
12584     case OMPD_taskloop_simd:
12585     case OMPD_master_taskloop:
12586     case OMPD_master_taskloop_simd:
12587     case OMPD_parallel_master_taskloop:
12588     case OMPD_parallel_master_taskloop_simd:
12589     case OMPD_cancel:
12590     case OMPD_parallel:
12591     case OMPD_parallel_master:
12592     case OMPD_parallel_sections:
12593     case OMPD_parallel_for:
12594     case OMPD_parallel_for_simd:
12595     case OMPD_threadprivate:
12596     case OMPD_allocate:
12597     case OMPD_taskyield:
12598     case OMPD_barrier:
12599     case OMPD_taskwait:
12600     case OMPD_cancellation_point:
12601     case OMPD_flush:
12602     case OMPD_depobj:
12603     case OMPD_scan:
12604     case OMPD_declare_reduction:
12605     case OMPD_declare_mapper:
12606     case OMPD_declare_simd:
12607     case OMPD_declare_variant:
12608     case OMPD_begin_declare_variant:
12609     case OMPD_end_declare_variant:
12610     case OMPD_declare_target:
12611     case OMPD_end_declare_target:
12612     case OMPD_simd:
12613     case OMPD_for:
12614     case OMPD_for_simd:
12615     case OMPD_sections:
12616     case OMPD_section:
12617     case OMPD_single:
12618     case OMPD_master:
12619     case OMPD_critical:
12620     case OMPD_taskgroup:
12621     case OMPD_distribute:
12622     case OMPD_ordered:
12623     case OMPD_atomic:
12624     case OMPD_distribute_simd:
12625     case OMPD_requires:
12626       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12627     case OMPD_unknown:
12628     default:
12629       llvm_unreachable("Unknown OpenMP directive");
12630     }
12631     break;
12632   case OMPC_grainsize:
12633   case OMPC_num_tasks:
12634   case OMPC_final:
12635   case OMPC_priority:
12636     switch (DKind) {
12637     case OMPD_task:
12638     case OMPD_taskloop:
12639     case OMPD_taskloop_simd:
12640     case OMPD_master_taskloop:
12641     case OMPD_master_taskloop_simd:
12642       break;
12643     case OMPD_parallel_master_taskloop:
12644     case OMPD_parallel_master_taskloop_simd:
12645       CaptureRegion = OMPD_parallel;
12646       break;
12647     case OMPD_target_update:
12648     case OMPD_target_enter_data:
12649     case OMPD_target_exit_data:
12650     case OMPD_target:
12651     case OMPD_target_simd:
12652     case OMPD_target_teams:
12653     case OMPD_target_parallel:
12654     case OMPD_target_teams_distribute:
12655     case OMPD_target_teams_distribute_simd:
12656     case OMPD_target_parallel_for:
12657     case OMPD_target_parallel_for_simd:
12658     case OMPD_target_teams_distribute_parallel_for:
12659     case OMPD_target_teams_distribute_parallel_for_simd:
12660     case OMPD_target_data:
12661     case OMPD_teams_distribute_parallel_for:
12662     case OMPD_teams_distribute_parallel_for_simd:
12663     case OMPD_teams:
12664     case OMPD_teams_distribute:
12665     case OMPD_teams_distribute_simd:
12666     case OMPD_distribute_parallel_for:
12667     case OMPD_distribute_parallel_for_simd:
12668     case OMPD_cancel:
12669     case OMPD_parallel:
12670     case OMPD_parallel_master:
12671     case OMPD_parallel_sections:
12672     case OMPD_parallel_for:
12673     case OMPD_parallel_for_simd:
12674     case OMPD_threadprivate:
12675     case OMPD_allocate:
12676     case OMPD_taskyield:
12677     case OMPD_barrier:
12678     case OMPD_taskwait:
12679     case OMPD_cancellation_point:
12680     case OMPD_flush:
12681     case OMPD_depobj:
12682     case OMPD_scan:
12683     case OMPD_declare_reduction:
12684     case OMPD_declare_mapper:
12685     case OMPD_declare_simd:
12686     case OMPD_declare_variant:
12687     case OMPD_begin_declare_variant:
12688     case OMPD_end_declare_variant:
12689     case OMPD_declare_target:
12690     case OMPD_end_declare_target:
12691     case OMPD_simd:
12692     case OMPD_for:
12693     case OMPD_for_simd:
12694     case OMPD_sections:
12695     case OMPD_section:
12696     case OMPD_single:
12697     case OMPD_master:
12698     case OMPD_critical:
12699     case OMPD_taskgroup:
12700     case OMPD_distribute:
12701     case OMPD_ordered:
12702     case OMPD_atomic:
12703     case OMPD_distribute_simd:
12704     case OMPD_requires:
12705       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
12706     case OMPD_unknown:
12707     default:
12708       llvm_unreachable("Unknown OpenMP directive");
12709     }
12710     break;
12711   case OMPC_firstprivate:
12712   case OMPC_lastprivate:
12713   case OMPC_reduction:
12714   case OMPC_task_reduction:
12715   case OMPC_in_reduction:
12716   case OMPC_linear:
12717   case OMPC_default:
12718   case OMPC_proc_bind:
12719   case OMPC_safelen:
12720   case OMPC_simdlen:
12721   case OMPC_allocator:
12722   case OMPC_collapse:
12723   case OMPC_private:
12724   case OMPC_shared:
12725   case OMPC_aligned:
12726   case OMPC_copyin:
12727   case OMPC_copyprivate:
12728   case OMPC_ordered:
12729   case OMPC_nowait:
12730   case OMPC_untied:
12731   case OMPC_mergeable:
12732   case OMPC_threadprivate:
12733   case OMPC_allocate:
12734   case OMPC_flush:
12735   case OMPC_depobj:
12736   case OMPC_read:
12737   case OMPC_write:
12738   case OMPC_update:
12739   case OMPC_capture:
12740   case OMPC_seq_cst:
12741   case OMPC_acq_rel:
12742   case OMPC_acquire:
12743   case OMPC_release:
12744   case OMPC_relaxed:
12745   case OMPC_depend:
12746   case OMPC_threads:
12747   case OMPC_simd:
12748   case OMPC_map:
12749   case OMPC_nogroup:
12750   case OMPC_hint:
12751   case OMPC_defaultmap:
12752   case OMPC_unknown:
12753   case OMPC_uniform:
12754   case OMPC_to:
12755   case OMPC_from:
12756   case OMPC_use_device_ptr:
12757   case OMPC_use_device_addr:
12758   case OMPC_is_device_ptr:
12759   case OMPC_unified_address:
12760   case OMPC_unified_shared_memory:
12761   case OMPC_reverse_offload:
12762   case OMPC_dynamic_allocators:
12763   case OMPC_atomic_default_mem_order:
12764   case OMPC_device_type:
12765   case OMPC_match:
12766   case OMPC_nontemporal:
12767   case OMPC_order:
12768   case OMPC_destroy:
12769   case OMPC_detach:
12770   case OMPC_inclusive:
12771   case OMPC_exclusive:
12772   case OMPC_uses_allocators:
12773   case OMPC_affinity:
12774   default:
12775     llvm_unreachable("Unexpected OpenMP clause.");
12776   }
12777   return CaptureRegion;
12778 }
12779 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)12780 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12781                                      Expr *Condition, SourceLocation StartLoc,
12782                                      SourceLocation LParenLoc,
12783                                      SourceLocation NameModifierLoc,
12784                                      SourceLocation ColonLoc,
12785                                      SourceLocation EndLoc) {
12786   Expr *ValExpr = Condition;
12787   Stmt *HelperValStmt = nullptr;
12788   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12789   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12790       !Condition->isInstantiationDependent() &&
12791       !Condition->containsUnexpandedParameterPack()) {
12792     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12793     if (Val.isInvalid())
12794       return nullptr;
12795 
12796     ValExpr = Val.get();
12797 
12798     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12799     CaptureRegion = getOpenMPCaptureRegionForClause(
12800         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12801     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12802       ValExpr = MakeFullExpr(ValExpr).get();
12803       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12804       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12805       HelperValStmt = buildPreInits(Context, Captures);
12806     }
12807   }
12808 
12809   return new (Context)
12810       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12811                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12812 }
12813 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12814 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12815                                         SourceLocation StartLoc,
12816                                         SourceLocation LParenLoc,
12817                                         SourceLocation EndLoc) {
12818   Expr *ValExpr = Condition;
12819   Stmt *HelperValStmt = nullptr;
12820   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12821   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12822       !Condition->isInstantiationDependent() &&
12823       !Condition->containsUnexpandedParameterPack()) {
12824     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12825     if (Val.isInvalid())
12826       return nullptr;
12827 
12828     ValExpr = MakeFullExpr(Val.get()).get();
12829 
12830     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12831     CaptureRegion =
12832         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12833     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12834       ValExpr = MakeFullExpr(ValExpr).get();
12835       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12836       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12837       HelperValStmt = buildPreInits(Context, Captures);
12838     }
12839   }
12840 
12841   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12842                                       StartLoc, LParenLoc, EndLoc);
12843 }
12844 
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)12845 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12846                                                         Expr *Op) {
12847   if (!Op)
12848     return ExprError();
12849 
12850   class IntConvertDiagnoser : public ICEConvertDiagnoser {
12851   public:
12852     IntConvertDiagnoser()
12853         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12854     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12855                                          QualType T) override {
12856       return S.Diag(Loc, diag::err_omp_not_integral) << T;
12857     }
12858     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12859                                              QualType T) override {
12860       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12861     }
12862     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12863                                                QualType T,
12864                                                QualType ConvTy) override {
12865       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12866     }
12867     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12868                                            QualType ConvTy) override {
12869       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12870              << ConvTy->isEnumeralType() << ConvTy;
12871     }
12872     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12873                                             QualType T) override {
12874       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12875     }
12876     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12877                                         QualType ConvTy) override {
12878       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12879              << ConvTy->isEnumeralType() << ConvTy;
12880     }
12881     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12882                                              QualType) override {
12883       llvm_unreachable("conversion functions are permitted");
12884     }
12885   } ConvertDiagnoser;
12886   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12887 }
12888 
12889 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)12890 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12891                           bool StrictlyPositive, bool BuildCapture = false,
12892                           OpenMPDirectiveKind DKind = OMPD_unknown,
12893                           OpenMPDirectiveKind *CaptureRegion = nullptr,
12894                           Stmt **HelperValStmt = nullptr) {
12895   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12896       !ValExpr->isInstantiationDependent()) {
12897     SourceLocation Loc = ValExpr->getExprLoc();
12898     ExprResult Value =
12899         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12900     if (Value.isInvalid())
12901       return false;
12902 
12903     ValExpr = Value.get();
12904     // The expression must evaluate to a non-negative integer value.
12905     if (Optional<llvm::APSInt> Result =
12906             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12907       if (Result->isSigned() &&
12908           !((!StrictlyPositive && Result->isNonNegative()) ||
12909             (StrictlyPositive && Result->isStrictlyPositive()))) {
12910         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12911             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12912             << ValExpr->getSourceRange();
12913         return false;
12914       }
12915     }
12916     if (!BuildCapture)
12917       return true;
12918     *CaptureRegion =
12919         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12920     if (*CaptureRegion != OMPD_unknown &&
12921         !SemaRef.CurContext->isDependentContext()) {
12922       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12923       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12924       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12925       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12926     }
12927   }
12928   return true;
12929 }
12930 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12931 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12932                                              SourceLocation StartLoc,
12933                                              SourceLocation LParenLoc,
12934                                              SourceLocation EndLoc) {
12935   Expr *ValExpr = NumThreads;
12936   Stmt *HelperValStmt = nullptr;
12937 
12938   // OpenMP [2.5, Restrictions]
12939   //  The num_threads expression must evaluate to a positive integer value.
12940   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12941                                  /*StrictlyPositive=*/true))
12942     return nullptr;
12943 
12944   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12945   OpenMPDirectiveKind CaptureRegion =
12946       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12947   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12948     ValExpr = MakeFullExpr(ValExpr).get();
12949     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12950     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12951     HelperValStmt = buildPreInits(Context, Captures);
12952   }
12953 
12954   return new (Context) OMPNumThreadsClause(
12955       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12956 }
12957 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)12958 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12959                                                        OpenMPClauseKind CKind,
12960                                                        bool StrictlyPositive) {
12961   if (!E)
12962     return ExprError();
12963   if (E->isValueDependent() || E->isTypeDependent() ||
12964       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12965     return E;
12966   llvm::APSInt Result;
12967   ExprResult ICE =
12968       VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
12969   if (ICE.isInvalid())
12970     return ExprError();
12971   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12972       (!StrictlyPositive && !Result.isNonNegative())) {
12973     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12974         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12975         << E->getSourceRange();
12976     return ExprError();
12977   }
12978   if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12979     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12980         << E->getSourceRange();
12981     return ExprError();
12982   }
12983   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
12984     DSAStack->setAssociatedLoops(Result.getExtValue());
12985   else if (CKind == OMPC_ordered)
12986     DSAStack->setAssociatedLoops(Result.getExtValue());
12987   return ICE;
12988 }
12989 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12990 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12991                                           SourceLocation LParenLoc,
12992                                           SourceLocation EndLoc) {
12993   // OpenMP [2.8.1, simd construct, Description]
12994   // The parameter of the safelen clause must be a constant
12995   // positive integer expression.
12996   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12997   if (Safelen.isInvalid())
12998     return nullptr;
12999   return new (Context)
13000       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
13001 }
13002 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13003 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
13004                                           SourceLocation LParenLoc,
13005                                           SourceLocation EndLoc) {
13006   // OpenMP [2.8.1, simd construct, Description]
13007   // The parameter of the simdlen clause must be a constant
13008   // positive integer expression.
13009   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13010   if (Simdlen.isInvalid())
13011     return nullptr;
13012   return new (Context)
13013       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13014 }
13015 
13016 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)13017 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13018                                     DSAStackTy *Stack) {
13019   QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13020   if (!OMPAllocatorHandleT.isNull())
13021     return true;
13022   // Build the predefined allocator expressions.
13023   bool ErrorFound = false;
13024   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13025     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13026     StringRef Allocator =
13027         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13028     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13029     auto *VD = dyn_cast_or_null<ValueDecl>(
13030         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13031     if (!VD) {
13032       ErrorFound = true;
13033       break;
13034     }
13035     QualType AllocatorType =
13036         VD->getType().getNonLValueExprType(S.getASTContext());
13037     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13038     if (!Res.isUsable()) {
13039       ErrorFound = true;
13040       break;
13041     }
13042     if (OMPAllocatorHandleT.isNull())
13043       OMPAllocatorHandleT = AllocatorType;
13044     if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13045       ErrorFound = true;
13046       break;
13047     }
13048     Stack->setAllocator(AllocatorKind, Res.get());
13049   }
13050   if (ErrorFound) {
13051     S.Diag(Loc, diag::err_omp_implied_type_not_found)
13052         << "omp_allocator_handle_t";
13053     return false;
13054   }
13055   OMPAllocatorHandleT.addConst();
13056   Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13057   return true;
13058 }
13059 
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13060 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13061                                             SourceLocation LParenLoc,
13062                                             SourceLocation EndLoc) {
13063   // OpenMP [2.11.3, allocate Directive, Description]
13064   // allocator is an expression of omp_allocator_handle_t type.
13065   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
13066     return nullptr;
13067 
13068   ExprResult Allocator = DefaultLvalueConversion(A);
13069   if (Allocator.isInvalid())
13070     return nullptr;
13071   Allocator = PerformImplicitConversion(Allocator.get(),
13072                                         DSAStack->getOMPAllocatorHandleT(),
13073                                         Sema::AA_Initializing,
13074                                         /*AllowExplicit=*/true);
13075   if (Allocator.isInvalid())
13076     return nullptr;
13077   return new (Context)
13078       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13079 }
13080 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13081 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
13082                                            SourceLocation StartLoc,
13083                                            SourceLocation LParenLoc,
13084                                            SourceLocation EndLoc) {
13085   // OpenMP [2.7.1, loop construct, Description]
13086   // OpenMP [2.8.1, simd construct, Description]
13087   // OpenMP [2.9.6, distribute construct, Description]
13088   // The parameter of the collapse clause must be a constant
13089   // positive integer expression.
13090   ExprResult NumForLoopsResult =
13091       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
13092   if (NumForLoopsResult.isInvalid())
13093     return nullptr;
13094   return new (Context)
13095       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
13096 }
13097 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)13098 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
13099                                           SourceLocation EndLoc,
13100                                           SourceLocation LParenLoc,
13101                                           Expr *NumForLoops) {
13102   // OpenMP [2.7.1, loop construct, Description]
13103   // OpenMP [2.8.1, simd construct, Description]
13104   // OpenMP [2.9.6, distribute construct, Description]
13105   // The parameter of the ordered clause must be a constant
13106   // positive integer expression if any.
13107   if (NumForLoops && LParenLoc.isValid()) {
13108     ExprResult NumForLoopsResult =
13109         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
13110     if (NumForLoopsResult.isInvalid())
13111       return nullptr;
13112     NumForLoops = NumForLoopsResult.get();
13113   } else {
13114     NumForLoops = nullptr;
13115   }
13116   auto *Clause = OMPOrderedClause::Create(
13117       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
13118       StartLoc, LParenLoc, EndLoc);
13119   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
13120   return Clause;
13121 }
13122 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13123 OMPClause *Sema::ActOnOpenMPSimpleClause(
13124     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
13125     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13126   OMPClause *Res = nullptr;
13127   switch (Kind) {
13128   case OMPC_default:
13129     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
13130                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13131     break;
13132   case OMPC_proc_bind:
13133     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
13134                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13135     break;
13136   case OMPC_atomic_default_mem_order:
13137     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
13138         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
13139         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13140     break;
13141   case OMPC_order:
13142     Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
13143                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13144     break;
13145   case OMPC_update:
13146     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
13147                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13148     break;
13149   case OMPC_if:
13150   case OMPC_final:
13151   case OMPC_num_threads:
13152   case OMPC_safelen:
13153   case OMPC_simdlen:
13154   case OMPC_allocator:
13155   case OMPC_collapse:
13156   case OMPC_schedule:
13157   case OMPC_private:
13158   case OMPC_firstprivate:
13159   case OMPC_lastprivate:
13160   case OMPC_shared:
13161   case OMPC_reduction:
13162   case OMPC_task_reduction:
13163   case OMPC_in_reduction:
13164   case OMPC_linear:
13165   case OMPC_aligned:
13166   case OMPC_copyin:
13167   case OMPC_copyprivate:
13168   case OMPC_ordered:
13169   case OMPC_nowait:
13170   case OMPC_untied:
13171   case OMPC_mergeable:
13172   case OMPC_threadprivate:
13173   case OMPC_allocate:
13174   case OMPC_flush:
13175   case OMPC_depobj:
13176   case OMPC_read:
13177   case OMPC_write:
13178   case OMPC_capture:
13179   case OMPC_seq_cst:
13180   case OMPC_acq_rel:
13181   case OMPC_acquire:
13182   case OMPC_release:
13183   case OMPC_relaxed:
13184   case OMPC_depend:
13185   case OMPC_device:
13186   case OMPC_threads:
13187   case OMPC_simd:
13188   case OMPC_map:
13189   case OMPC_num_teams:
13190   case OMPC_thread_limit:
13191   case OMPC_priority:
13192   case OMPC_grainsize:
13193   case OMPC_nogroup:
13194   case OMPC_num_tasks:
13195   case OMPC_hint:
13196   case OMPC_dist_schedule:
13197   case OMPC_defaultmap:
13198   case OMPC_unknown:
13199   case OMPC_uniform:
13200   case OMPC_to:
13201   case OMPC_from:
13202   case OMPC_use_device_ptr:
13203   case OMPC_use_device_addr:
13204   case OMPC_is_device_ptr:
13205   case OMPC_unified_address:
13206   case OMPC_unified_shared_memory:
13207   case OMPC_reverse_offload:
13208   case OMPC_dynamic_allocators:
13209   case OMPC_device_type:
13210   case OMPC_match:
13211   case OMPC_nontemporal:
13212   case OMPC_destroy:
13213   case OMPC_detach:
13214   case OMPC_inclusive:
13215   case OMPC_exclusive:
13216   case OMPC_uses_allocators:
13217   case OMPC_affinity:
13218   default:
13219     llvm_unreachable("Clause is not allowed.");
13220   }
13221   return Res;
13222 }
13223 
13224 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)13225 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13226                         ArrayRef<unsigned> Exclude = llvm::None) {
13227   SmallString<256> Buffer;
13228   llvm::raw_svector_ostream Out(Buffer);
13229   unsigned Skipped = Exclude.size();
13230   auto S = Exclude.begin(), E = Exclude.end();
13231   for (unsigned I = First; I < Last; ++I) {
13232     if (std::find(S, E, I) != E) {
13233       --Skipped;
13234       continue;
13235     }
13236     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13237     if (I + Skipped + 2 == Last)
13238       Out << " or ";
13239     else if (I + Skipped + 1 != Last)
13240       Out << ", ";
13241   }
13242   return std::string(Out.str());
13243 }
13244 
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13245 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13246                                           SourceLocation KindKwLoc,
13247                                           SourceLocation StartLoc,
13248                                           SourceLocation LParenLoc,
13249                                           SourceLocation EndLoc) {
13250   if (Kind == OMP_DEFAULT_unknown) {
13251     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13252         << getListOfPossibleValues(OMPC_default, /*First=*/0,
13253                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
13254         << getOpenMPClauseName(OMPC_default);
13255     return nullptr;
13256   }
13257 
13258   switch (Kind) {
13259   case OMP_DEFAULT_none:
13260     DSAStack->setDefaultDSANone(KindKwLoc);
13261     break;
13262   case OMP_DEFAULT_shared:
13263     DSAStack->setDefaultDSAShared(KindKwLoc);
13264     break;
13265   case OMP_DEFAULT_firstprivate:
13266     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
13267     break;
13268   default:
13269     llvm_unreachable("DSA unexpected in OpenMP default clause");
13270   }
13271 
13272   return new (Context)
13273       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13274 }
13275 
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13276 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13277                                            SourceLocation KindKwLoc,
13278                                            SourceLocation StartLoc,
13279                                            SourceLocation LParenLoc,
13280                                            SourceLocation EndLoc) {
13281   if (Kind == OMP_PROC_BIND_unknown) {
13282     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13283         << getListOfPossibleValues(OMPC_proc_bind,
13284                                    /*First=*/unsigned(OMP_PROC_BIND_master),
13285                                    /*Last=*/5)
13286         << getOpenMPClauseName(OMPC_proc_bind);
13287     return nullptr;
13288   }
13289   return new (Context)
13290       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13291 }
13292 
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13293 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13294     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13295     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13296   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13297     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13298         << getListOfPossibleValues(
13299                OMPC_atomic_default_mem_order, /*First=*/0,
13300                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13301         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13302     return nullptr;
13303   }
13304   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13305                                                       LParenLoc, EndLoc);
13306 }
13307 
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13308 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13309                                         SourceLocation KindKwLoc,
13310                                         SourceLocation StartLoc,
13311                                         SourceLocation LParenLoc,
13312                                         SourceLocation EndLoc) {
13313   if (Kind == OMPC_ORDER_unknown) {
13314     static_assert(OMPC_ORDER_unknown > 0,
13315                   "OMPC_ORDER_unknown not greater than 0");
13316     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13317         << getListOfPossibleValues(OMPC_order, /*First=*/0,
13318                                    /*Last=*/OMPC_ORDER_unknown)
13319         << getOpenMPClauseName(OMPC_order);
13320     return nullptr;
13321   }
13322   return new (Context)
13323       OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13324 }
13325 
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13326 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13327                                          SourceLocation KindKwLoc,
13328                                          SourceLocation StartLoc,
13329                                          SourceLocation LParenLoc,
13330                                          SourceLocation EndLoc) {
13331   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13332       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13333     unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13334                          OMPC_DEPEND_depobj};
13335     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13336         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13337                                    /*Last=*/OMPC_DEPEND_unknown, Except)
13338         << getOpenMPClauseName(OMPC_update);
13339     return nullptr;
13340   }
13341   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13342                                  EndLoc);
13343 }
13344 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)13345 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13346     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13347     SourceLocation StartLoc, SourceLocation LParenLoc,
13348     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13349     SourceLocation EndLoc) {
13350   OMPClause *Res = nullptr;
13351   switch (Kind) {
13352   case OMPC_schedule:
13353     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13354     assert(Argument.size() == NumberOfElements &&
13355            ArgumentLoc.size() == NumberOfElements);
13356     Res = ActOnOpenMPScheduleClause(
13357         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13358         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13359         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13360         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13361         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13362     break;
13363   case OMPC_if:
13364     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13365     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13366                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13367                               DelimLoc, EndLoc);
13368     break;
13369   case OMPC_dist_schedule:
13370     Res = ActOnOpenMPDistScheduleClause(
13371         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13372         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13373     break;
13374   case OMPC_defaultmap:
13375     enum { Modifier, DefaultmapKind };
13376     Res = ActOnOpenMPDefaultmapClause(
13377         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13378         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13379         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13380         EndLoc);
13381     break;
13382   case OMPC_device:
13383     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13384     Res = ActOnOpenMPDeviceClause(
13385         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13386         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13387     break;
13388   case OMPC_final:
13389   case OMPC_num_threads:
13390   case OMPC_safelen:
13391   case OMPC_simdlen:
13392   case OMPC_allocator:
13393   case OMPC_collapse:
13394   case OMPC_default:
13395   case OMPC_proc_bind:
13396   case OMPC_private:
13397   case OMPC_firstprivate:
13398   case OMPC_lastprivate:
13399   case OMPC_shared:
13400   case OMPC_reduction:
13401   case OMPC_task_reduction:
13402   case OMPC_in_reduction:
13403   case OMPC_linear:
13404   case OMPC_aligned:
13405   case OMPC_copyin:
13406   case OMPC_copyprivate:
13407   case OMPC_ordered:
13408   case OMPC_nowait:
13409   case OMPC_untied:
13410   case OMPC_mergeable:
13411   case OMPC_threadprivate:
13412   case OMPC_allocate:
13413   case OMPC_flush:
13414   case OMPC_depobj:
13415   case OMPC_read:
13416   case OMPC_write:
13417   case OMPC_update:
13418   case OMPC_capture:
13419   case OMPC_seq_cst:
13420   case OMPC_acq_rel:
13421   case OMPC_acquire:
13422   case OMPC_release:
13423   case OMPC_relaxed:
13424   case OMPC_depend:
13425   case OMPC_threads:
13426   case OMPC_simd:
13427   case OMPC_map:
13428   case OMPC_num_teams:
13429   case OMPC_thread_limit:
13430   case OMPC_priority:
13431   case OMPC_grainsize:
13432   case OMPC_nogroup:
13433   case OMPC_num_tasks:
13434   case OMPC_hint:
13435   case OMPC_unknown:
13436   case OMPC_uniform:
13437   case OMPC_to:
13438   case OMPC_from:
13439   case OMPC_use_device_ptr:
13440   case OMPC_use_device_addr:
13441   case OMPC_is_device_ptr:
13442   case OMPC_unified_address:
13443   case OMPC_unified_shared_memory:
13444   case OMPC_reverse_offload:
13445   case OMPC_dynamic_allocators:
13446   case OMPC_atomic_default_mem_order:
13447   case OMPC_device_type:
13448   case OMPC_match:
13449   case OMPC_nontemporal:
13450   case OMPC_order:
13451   case OMPC_destroy:
13452   case OMPC_detach:
13453   case OMPC_inclusive:
13454   case OMPC_exclusive:
13455   case OMPC_uses_allocators:
13456   case OMPC_affinity:
13457   default:
13458     llvm_unreachable("Clause is not allowed.");
13459   }
13460   return Res;
13461 }
13462 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)13463 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13464                                    OpenMPScheduleClauseModifier M2,
13465                                    SourceLocation M1Loc, SourceLocation M2Loc) {
13466   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13467     SmallVector<unsigned, 2> Excluded;
13468     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13469       Excluded.push_back(M2);
13470     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13471       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13472     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13473       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13474     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13475         << getListOfPossibleValues(OMPC_schedule,
13476                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13477                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13478                                    Excluded)
13479         << getOpenMPClauseName(OMPC_schedule);
13480     return true;
13481   }
13482   return false;
13483 }
13484 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)13485 OMPClause *Sema::ActOnOpenMPScheduleClause(
13486     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13487     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13488     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13489     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13490   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13491       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13492     return nullptr;
13493   // OpenMP, 2.7.1, Loop Construct, Restrictions
13494   // Either the monotonic modifier or the nonmonotonic modifier can be specified
13495   // but not both.
13496   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13497       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13498        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13499       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13500        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13501     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13502         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13503         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13504     return nullptr;
13505   }
13506   if (Kind == OMPC_SCHEDULE_unknown) {
13507     std::string Values;
13508     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13509       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13510       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13511                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13512                                        Exclude);
13513     } else {
13514       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13515                                        /*Last=*/OMPC_SCHEDULE_unknown);
13516     }
13517     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13518         << Values << getOpenMPClauseName(OMPC_schedule);
13519     return nullptr;
13520   }
13521   // OpenMP, 2.7.1, Loop Construct, Restrictions
13522   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13523   // schedule(guided).
13524   // OpenMP 5.0 does not have this restriction.
13525   if (LangOpts.OpenMP < 50 &&
13526       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13527        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13528       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13529     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13530          diag::err_omp_schedule_nonmonotonic_static);
13531     return nullptr;
13532   }
13533   Expr *ValExpr = ChunkSize;
13534   Stmt *HelperValStmt = nullptr;
13535   if (ChunkSize) {
13536     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13537         !ChunkSize->isInstantiationDependent() &&
13538         !ChunkSize->containsUnexpandedParameterPack()) {
13539       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13540       ExprResult Val =
13541           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13542       if (Val.isInvalid())
13543         return nullptr;
13544 
13545       ValExpr = Val.get();
13546 
13547       // OpenMP [2.7.1, Restrictions]
13548       //  chunk_size must be a loop invariant integer expression with a positive
13549       //  value.
13550       if (Optional<llvm::APSInt> Result =
13551               ValExpr->getIntegerConstantExpr(Context)) {
13552         if (Result->isSigned() && !Result->isStrictlyPositive()) {
13553           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13554               << "schedule" << 1 << ChunkSize->getSourceRange();
13555           return nullptr;
13556         }
13557       } else if (getOpenMPCaptureRegionForClause(
13558                      DSAStack->getCurrentDirective(), OMPC_schedule,
13559                      LangOpts.OpenMP) != OMPD_unknown &&
13560                  !CurContext->isDependentContext()) {
13561         ValExpr = MakeFullExpr(ValExpr).get();
13562         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13563         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13564         HelperValStmt = buildPreInits(Context, Captures);
13565       }
13566     }
13567   }
13568 
13569   return new (Context)
13570       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13571                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13572 }
13573 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)13574 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13575                                    SourceLocation StartLoc,
13576                                    SourceLocation EndLoc) {
13577   OMPClause *Res = nullptr;
13578   switch (Kind) {
13579   case OMPC_ordered:
13580     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13581     break;
13582   case OMPC_nowait:
13583     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13584     break;
13585   case OMPC_untied:
13586     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13587     break;
13588   case OMPC_mergeable:
13589     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13590     break;
13591   case OMPC_read:
13592     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13593     break;
13594   case OMPC_write:
13595     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13596     break;
13597   case OMPC_update:
13598     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13599     break;
13600   case OMPC_capture:
13601     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13602     break;
13603   case OMPC_seq_cst:
13604     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13605     break;
13606   case OMPC_acq_rel:
13607     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13608     break;
13609   case OMPC_acquire:
13610     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13611     break;
13612   case OMPC_release:
13613     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13614     break;
13615   case OMPC_relaxed:
13616     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13617     break;
13618   case OMPC_threads:
13619     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13620     break;
13621   case OMPC_simd:
13622     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13623     break;
13624   case OMPC_nogroup:
13625     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13626     break;
13627   case OMPC_unified_address:
13628     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13629     break;
13630   case OMPC_unified_shared_memory:
13631     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13632     break;
13633   case OMPC_reverse_offload:
13634     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13635     break;
13636   case OMPC_dynamic_allocators:
13637     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13638     break;
13639   case OMPC_destroy:
13640     Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13641     break;
13642   case OMPC_if:
13643   case OMPC_final:
13644   case OMPC_num_threads:
13645   case OMPC_safelen:
13646   case OMPC_simdlen:
13647   case OMPC_allocator:
13648   case OMPC_collapse:
13649   case OMPC_schedule:
13650   case OMPC_private:
13651   case OMPC_firstprivate:
13652   case OMPC_lastprivate:
13653   case OMPC_shared:
13654   case OMPC_reduction:
13655   case OMPC_task_reduction:
13656   case OMPC_in_reduction:
13657   case OMPC_linear:
13658   case OMPC_aligned:
13659   case OMPC_copyin:
13660   case OMPC_copyprivate:
13661   case OMPC_default:
13662   case OMPC_proc_bind:
13663   case OMPC_threadprivate:
13664   case OMPC_allocate:
13665   case OMPC_flush:
13666   case OMPC_depobj:
13667   case OMPC_depend:
13668   case OMPC_device:
13669   case OMPC_map:
13670   case OMPC_num_teams:
13671   case OMPC_thread_limit:
13672   case OMPC_priority:
13673   case OMPC_grainsize:
13674   case OMPC_num_tasks:
13675   case OMPC_hint:
13676   case OMPC_dist_schedule:
13677   case OMPC_defaultmap:
13678   case OMPC_unknown:
13679   case OMPC_uniform:
13680   case OMPC_to:
13681   case OMPC_from:
13682   case OMPC_use_device_ptr:
13683   case OMPC_use_device_addr:
13684   case OMPC_is_device_ptr:
13685   case OMPC_atomic_default_mem_order:
13686   case OMPC_device_type:
13687   case OMPC_match:
13688   case OMPC_nontemporal:
13689   case OMPC_order:
13690   case OMPC_detach:
13691   case OMPC_inclusive:
13692   case OMPC_exclusive:
13693   case OMPC_uses_allocators:
13694   case OMPC_affinity:
13695   default:
13696     llvm_unreachable("Clause is not allowed.");
13697   }
13698   return Res;
13699 }
13700 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)13701 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13702                                          SourceLocation EndLoc) {
13703   DSAStack->setNowaitRegion();
13704   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13705 }
13706 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)13707 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13708                                          SourceLocation EndLoc) {
13709   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13710 }
13711 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)13712 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13713                                             SourceLocation EndLoc) {
13714   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13715 }
13716 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)13717 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13718                                        SourceLocation EndLoc) {
13719   return new (Context) OMPReadClause(StartLoc, EndLoc);
13720 }
13721 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)13722 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13723                                         SourceLocation EndLoc) {
13724   return new (Context) OMPWriteClause(StartLoc, EndLoc);
13725 }
13726 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)13727 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13728                                          SourceLocation EndLoc) {
13729   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13730 }
13731 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)13732 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13733                                           SourceLocation EndLoc) {
13734   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13735 }
13736 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)13737 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13738                                          SourceLocation EndLoc) {
13739   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13740 }
13741 
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)13742 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13743                                          SourceLocation EndLoc) {
13744   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13745 }
13746 
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)13747 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13748                                           SourceLocation EndLoc) {
13749   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13750 }
13751 
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)13752 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13753                                           SourceLocation EndLoc) {
13754   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13755 }
13756 
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)13757 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13758                                           SourceLocation EndLoc) {
13759   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13760 }
13761 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)13762 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13763                                           SourceLocation EndLoc) {
13764   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13765 }
13766 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)13767 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13768                                        SourceLocation EndLoc) {
13769   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13770 }
13771 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)13772 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13773                                           SourceLocation EndLoc) {
13774   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13775 }
13776 
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)13777 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13778                                                  SourceLocation EndLoc) {
13779   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13780 }
13781 
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)13782 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13783                                                       SourceLocation EndLoc) {
13784   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13785 }
13786 
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)13787 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13788                                                  SourceLocation EndLoc) {
13789   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13790 }
13791 
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)13792 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13793                                                     SourceLocation EndLoc) {
13794   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13795 }
13796 
ActOnOpenMPDestroyClause(SourceLocation StartLoc,SourceLocation EndLoc)13797 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13798                                           SourceLocation EndLoc) {
13799   return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13800 }
13801 
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)13802 OMPClause *Sema::ActOnOpenMPVarListClause(
13803     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13804     const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13805     CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13806     DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13807     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13808     ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13809     SourceLocation ExtraModifierLoc,
13810     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13811     ArrayRef<SourceLocation> MotionModifiersLoc) {
13812   SourceLocation StartLoc = Locs.StartLoc;
13813   SourceLocation LParenLoc = Locs.LParenLoc;
13814   SourceLocation EndLoc = Locs.EndLoc;
13815   OMPClause *Res = nullptr;
13816   switch (Kind) {
13817   case OMPC_private:
13818     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13819     break;
13820   case OMPC_firstprivate:
13821     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13822     break;
13823   case OMPC_lastprivate:
13824     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
13825            "Unexpected lastprivate modifier.");
13826     Res = ActOnOpenMPLastprivateClause(
13827         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13828         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13829     break;
13830   case OMPC_shared:
13831     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13832     break;
13833   case OMPC_reduction:
13834     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
13835            "Unexpected lastprivate modifier.");
13836     Res = ActOnOpenMPReductionClause(
13837         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13838         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13839         ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13840     break;
13841   case OMPC_task_reduction:
13842     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13843                                          EndLoc, ReductionOrMapperIdScopeSpec,
13844                                          ReductionOrMapperId);
13845     break;
13846   case OMPC_in_reduction:
13847     Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13848                                        EndLoc, ReductionOrMapperIdScopeSpec,
13849                                        ReductionOrMapperId);
13850     break;
13851   case OMPC_linear:
13852     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
13853            "Unexpected linear modifier.");
13854     Res = ActOnOpenMPLinearClause(
13855         VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13856         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13857         ColonLoc, EndLoc);
13858     break;
13859   case OMPC_aligned:
13860     Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13861                                    LParenLoc, ColonLoc, EndLoc);
13862     break;
13863   case OMPC_copyin:
13864     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13865     break;
13866   case OMPC_copyprivate:
13867     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13868     break;
13869   case OMPC_flush:
13870     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13871     break;
13872   case OMPC_depend:
13873     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
13874            "Unexpected depend modifier.");
13875     Res = ActOnOpenMPDependClause(
13876         DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13877         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13878     break;
13879   case OMPC_map:
13880     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
13881            "Unexpected map modifier.");
13882     Res = ActOnOpenMPMapClause(
13883         MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13884         ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13885         IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13886     break;
13887   case OMPC_to:
13888     Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13889                               ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13890                               ColonLoc, VarList, Locs);
13891     break;
13892   case OMPC_from:
13893     Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13894                                 ReductionOrMapperIdScopeSpec,
13895                                 ReductionOrMapperId, ColonLoc, VarList, Locs);
13896     break;
13897   case OMPC_use_device_ptr:
13898     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13899     break;
13900   case OMPC_use_device_addr:
13901     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13902     break;
13903   case OMPC_is_device_ptr:
13904     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13905     break;
13906   case OMPC_allocate:
13907     Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13908                                     LParenLoc, ColonLoc, EndLoc);
13909     break;
13910   case OMPC_nontemporal:
13911     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13912     break;
13913   case OMPC_inclusive:
13914     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13915     break;
13916   case OMPC_exclusive:
13917     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13918     break;
13919   case OMPC_affinity:
13920     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13921                                     DepModOrTailExpr, VarList);
13922     break;
13923   case OMPC_if:
13924   case OMPC_depobj:
13925   case OMPC_final:
13926   case OMPC_num_threads:
13927   case OMPC_safelen:
13928   case OMPC_simdlen:
13929   case OMPC_allocator:
13930   case OMPC_collapse:
13931   case OMPC_default:
13932   case OMPC_proc_bind:
13933   case OMPC_schedule:
13934   case OMPC_ordered:
13935   case OMPC_nowait:
13936   case OMPC_untied:
13937   case OMPC_mergeable:
13938   case OMPC_threadprivate:
13939   case OMPC_read:
13940   case OMPC_write:
13941   case OMPC_update:
13942   case OMPC_capture:
13943   case OMPC_seq_cst:
13944   case OMPC_acq_rel:
13945   case OMPC_acquire:
13946   case OMPC_release:
13947   case OMPC_relaxed:
13948   case OMPC_device:
13949   case OMPC_threads:
13950   case OMPC_simd:
13951   case OMPC_num_teams:
13952   case OMPC_thread_limit:
13953   case OMPC_priority:
13954   case OMPC_grainsize:
13955   case OMPC_nogroup:
13956   case OMPC_num_tasks:
13957   case OMPC_hint:
13958   case OMPC_dist_schedule:
13959   case OMPC_defaultmap:
13960   case OMPC_unknown:
13961   case OMPC_uniform:
13962   case OMPC_unified_address:
13963   case OMPC_unified_shared_memory:
13964   case OMPC_reverse_offload:
13965   case OMPC_dynamic_allocators:
13966   case OMPC_atomic_default_mem_order:
13967   case OMPC_device_type:
13968   case OMPC_match:
13969   case OMPC_order:
13970   case OMPC_destroy:
13971   case OMPC_detach:
13972   case OMPC_uses_allocators:
13973   default:
13974     llvm_unreachable("Clause is not allowed.");
13975   }
13976   return Res;
13977 }
13978 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)13979 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13980                                        ExprObjectKind OK, SourceLocation Loc) {
13981   ExprResult Res = BuildDeclRefExpr(
13982       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13983   if (!Res.isUsable())
13984     return ExprError();
13985   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13986     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13987     if (!Res.isUsable())
13988       return ExprError();
13989   }
13990   if (VK != VK_LValue && Res.get()->isGLValue()) {
13991     Res = DefaultLvalueConversion(Res.get());
13992     if (!Res.isUsable())
13993       return ExprError();
13994   }
13995   return Res;
13996 }
13997 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13998 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13999                                           SourceLocation StartLoc,
14000                                           SourceLocation LParenLoc,
14001                                           SourceLocation EndLoc) {
14002   SmallVector<Expr *, 8> Vars;
14003   SmallVector<Expr *, 8> PrivateCopies;
14004   for (Expr *RefExpr : VarList) {
14005     assert(RefExpr && "NULL expr in OpenMP private clause.");
14006     SourceLocation ELoc;
14007     SourceRange ERange;
14008     Expr *SimpleRefExpr = RefExpr;
14009     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14010     if (Res.second) {
14011       // It will be analyzed later.
14012       Vars.push_back(RefExpr);
14013       PrivateCopies.push_back(nullptr);
14014     }
14015     ValueDecl *D = Res.first;
14016     if (!D)
14017       continue;
14018 
14019     QualType Type = D->getType();
14020     auto *VD = dyn_cast<VarDecl>(D);
14021 
14022     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14023     //  A variable that appears in a private clause must not have an incomplete
14024     //  type or a reference type.
14025     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
14026       continue;
14027     Type = Type.getNonReferenceType();
14028 
14029     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14030     // A variable that is privatized must not have a const-qualified type
14031     // unless it is of class type with a mutable member. This restriction does
14032     // not apply to the firstprivate clause.
14033     //
14034     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
14035     // A variable that appears in a private clause must not have a
14036     // const-qualified type unless it is of class type with a mutable member.
14037     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
14038       continue;
14039 
14040     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14041     // in a Construct]
14042     //  Variables with the predetermined data-sharing attributes may not be
14043     //  listed in data-sharing attributes clauses, except for the cases
14044     //  listed below. For these exceptions only, listing a predetermined
14045     //  variable in a data-sharing attribute clause is allowed and overrides
14046     //  the variable's predetermined data-sharing attributes.
14047     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14048     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
14049       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14050                                           << getOpenMPClauseName(OMPC_private);
14051       reportOriginalDsa(*this, DSAStack, D, DVar);
14052       continue;
14053     }
14054 
14055     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14056     // Variably modified types are not supported for tasks.
14057     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14058         isOpenMPTaskingDirective(CurrDir)) {
14059       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14060           << getOpenMPClauseName(OMPC_private) << Type
14061           << getOpenMPDirectiveName(CurrDir);
14062       bool IsDecl =
14063           !VD ||
14064           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14065       Diag(D->getLocation(),
14066            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14067           << D;
14068       continue;
14069     }
14070 
14071     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14072     // A list item cannot appear in both a map clause and a data-sharing
14073     // attribute clause on the same construct
14074     //
14075     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14076     // A list item cannot appear in both a map clause and a data-sharing
14077     // attribute clause on the same construct unless the construct is a
14078     // combined construct.
14079     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
14080         CurrDir == OMPD_target) {
14081       OpenMPClauseKind ConflictKind;
14082       if (DSAStack->checkMappableExprComponentListsForDecl(
14083               VD, /*CurrentRegionOnly=*/true,
14084               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
14085                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
14086                 ConflictKind = WhereFoundClauseKind;
14087                 return true;
14088               })) {
14089         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14090             << getOpenMPClauseName(OMPC_private)
14091             << getOpenMPClauseName(ConflictKind)
14092             << getOpenMPDirectiveName(CurrDir);
14093         reportOriginalDsa(*this, DSAStack, D, DVar);
14094         continue;
14095       }
14096     }
14097 
14098     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
14099     //  A variable of class type (or array thereof) that appears in a private
14100     //  clause requires an accessible, unambiguous default constructor for the
14101     //  class type.
14102     // Generate helper private variable and initialize it with the default
14103     // value. The address of the original variable is replaced by the address of
14104     // the new private variable in CodeGen. This new variable is not added to
14105     // IdResolver, so the code in the OpenMP region uses original variable for
14106     // proper diagnostics.
14107     Type = Type.getUnqualifiedType();
14108     VarDecl *VDPrivate =
14109         buildVarDecl(*this, ELoc, Type, D->getName(),
14110                      D->hasAttrs() ? &D->getAttrs() : nullptr,
14111                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14112     ActOnUninitializedDecl(VDPrivate);
14113     if (VDPrivate->isInvalidDecl())
14114       continue;
14115     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14116         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
14117 
14118     DeclRefExpr *Ref = nullptr;
14119     if (!VD && !CurContext->isDependentContext())
14120       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14121     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
14122     Vars.push_back((VD || CurContext->isDependentContext())
14123                        ? RefExpr->IgnoreParens()
14124                        : Ref);
14125     PrivateCopies.push_back(VDPrivateRefExpr);
14126   }
14127 
14128   if (Vars.empty())
14129     return nullptr;
14130 
14131   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14132                                   PrivateCopies);
14133 }
14134 
14135 namespace {
14136 class DiagsUninitializedSeveretyRAII {
14137 private:
14138   DiagnosticsEngine &Diags;
14139   SourceLocation SavedLoc;
14140   bool IsIgnored = false;
14141 
14142 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)14143   DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
14144                                  bool IsIgnored)
14145       : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
14146     if (!IsIgnored) {
14147       Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
14148                         /*Map*/ diag::Severity::Ignored, Loc);
14149     }
14150   }
~DiagsUninitializedSeveretyRAII()14151   ~DiagsUninitializedSeveretyRAII() {
14152     if (!IsIgnored)
14153       Diags.popMappings(SavedLoc);
14154   }
14155 };
14156 }
14157 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14158 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
14159                                                SourceLocation StartLoc,
14160                                                SourceLocation LParenLoc,
14161                                                SourceLocation EndLoc) {
14162   SmallVector<Expr *, 8> Vars;
14163   SmallVector<Expr *, 8> PrivateCopies;
14164   SmallVector<Expr *, 8> Inits;
14165   SmallVector<Decl *, 4> ExprCaptures;
14166   bool IsImplicitClause =
14167       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14168   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
14169 
14170   for (Expr *RefExpr : VarList) {
14171     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
14172     SourceLocation ELoc;
14173     SourceRange ERange;
14174     Expr *SimpleRefExpr = RefExpr;
14175     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14176     if (Res.second) {
14177       // It will be analyzed later.
14178       Vars.push_back(RefExpr);
14179       PrivateCopies.push_back(nullptr);
14180       Inits.push_back(nullptr);
14181     }
14182     ValueDecl *D = Res.first;
14183     if (!D)
14184       continue;
14185 
14186     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14187     QualType Type = D->getType();
14188     auto *VD = dyn_cast<VarDecl>(D);
14189 
14190     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14191     //  A variable that appears in a private clause must not have an incomplete
14192     //  type or a reference type.
14193     if (RequireCompleteType(ELoc, Type,
14194                             diag::err_omp_firstprivate_incomplete_type))
14195       continue;
14196     Type = Type.getNonReferenceType();
14197 
14198     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14199     //  A variable of class type (or array thereof) that appears in a private
14200     //  clause requires an accessible, unambiguous copy constructor for the
14201     //  class type.
14202     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14203 
14204     // If an implicit firstprivate variable found it was checked already.
14205     DSAStackTy::DSAVarData TopDVar;
14206     if (!IsImplicitClause) {
14207       DSAStackTy::DSAVarData DVar =
14208           DSAStack->getTopDSA(D, /*FromParent=*/false);
14209       TopDVar = DVar;
14210       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14211       bool IsConstant = ElemType.isConstant(Context);
14212       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14213       //  A list item that specifies a given variable may not appear in more
14214       // than one clause on the same directive, except that a variable may be
14215       //  specified in both firstprivate and lastprivate clauses.
14216       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14217       // A list item may appear in a firstprivate or lastprivate clause but not
14218       // both.
14219       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14220           (isOpenMPDistributeDirective(CurrDir) ||
14221            DVar.CKind != OMPC_lastprivate) &&
14222           DVar.RefExpr) {
14223         Diag(ELoc, diag::err_omp_wrong_dsa)
14224             << getOpenMPClauseName(DVar.CKind)
14225             << getOpenMPClauseName(OMPC_firstprivate);
14226         reportOriginalDsa(*this, DSAStack, D, DVar);
14227         continue;
14228       }
14229 
14230       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14231       // in a Construct]
14232       //  Variables with the predetermined data-sharing attributes may not be
14233       //  listed in data-sharing attributes clauses, except for the cases
14234       //  listed below. For these exceptions only, listing a predetermined
14235       //  variable in a data-sharing attribute clause is allowed and overrides
14236       //  the variable's predetermined data-sharing attributes.
14237       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14238       // in a Construct, C/C++, p.2]
14239       //  Variables with const-qualified type having no mutable member may be
14240       //  listed in a firstprivate clause, even if they are static data members.
14241       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14242           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14243         Diag(ELoc, diag::err_omp_wrong_dsa)
14244             << getOpenMPClauseName(DVar.CKind)
14245             << getOpenMPClauseName(OMPC_firstprivate);
14246         reportOriginalDsa(*this, DSAStack, D, DVar);
14247         continue;
14248       }
14249 
14250       // OpenMP [2.9.3.4, Restrictions, p.2]
14251       //  A list item that is private within a parallel region must not appear
14252       //  in a firstprivate clause on a worksharing construct if any of the
14253       //  worksharing regions arising from the worksharing construct ever bind
14254       //  to any of the parallel regions arising from the parallel construct.
14255       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14256       // A list item that is private within a teams region must not appear in a
14257       // firstprivate clause on a distribute construct if any of the distribute
14258       // regions arising from the distribute construct ever bind to any of the
14259       // teams regions arising from the teams construct.
14260       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14261       // A list item that appears in a reduction clause of a teams construct
14262       // must not appear in a firstprivate clause on a distribute construct if
14263       // any of the distribute regions arising from the distribute construct
14264       // ever bind to any of the teams regions arising from the teams construct.
14265       if ((isOpenMPWorksharingDirective(CurrDir) ||
14266            isOpenMPDistributeDirective(CurrDir)) &&
14267           !isOpenMPParallelDirective(CurrDir) &&
14268           !isOpenMPTeamsDirective(CurrDir)) {
14269         DVar = DSAStack->getImplicitDSA(D, true);
14270         if (DVar.CKind != OMPC_shared &&
14271             (isOpenMPParallelDirective(DVar.DKind) ||
14272              isOpenMPTeamsDirective(DVar.DKind) ||
14273              DVar.DKind == OMPD_unknown)) {
14274           Diag(ELoc, diag::err_omp_required_access)
14275               << getOpenMPClauseName(OMPC_firstprivate)
14276               << getOpenMPClauseName(OMPC_shared);
14277           reportOriginalDsa(*this, DSAStack, D, DVar);
14278           continue;
14279         }
14280       }
14281       // OpenMP [2.9.3.4, Restrictions, p.3]
14282       //  A list item that appears in a reduction clause of a parallel construct
14283       //  must not appear in a firstprivate clause on a worksharing or task
14284       //  construct if any of the worksharing or task regions arising from the
14285       //  worksharing or task construct ever bind to any of the parallel regions
14286       //  arising from the parallel construct.
14287       // OpenMP [2.9.3.4, Restrictions, p.4]
14288       //  A list item that appears in a reduction clause in worksharing
14289       //  construct must not appear in a firstprivate clause in a task construct
14290       //  encountered during execution of any of the worksharing regions arising
14291       //  from the worksharing construct.
14292       if (isOpenMPTaskingDirective(CurrDir)) {
14293         DVar = DSAStack->hasInnermostDSA(
14294             D,
14295             [](OpenMPClauseKind C, bool AppliedToPointee) {
14296               return C == OMPC_reduction && !AppliedToPointee;
14297             },
14298             [](OpenMPDirectiveKind K) {
14299               return isOpenMPParallelDirective(K) ||
14300                      isOpenMPWorksharingDirective(K) ||
14301                      isOpenMPTeamsDirective(K);
14302             },
14303             /*FromParent=*/true);
14304         if (DVar.CKind == OMPC_reduction &&
14305             (isOpenMPParallelDirective(DVar.DKind) ||
14306              isOpenMPWorksharingDirective(DVar.DKind) ||
14307              isOpenMPTeamsDirective(DVar.DKind))) {
14308           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14309               << getOpenMPDirectiveName(DVar.DKind);
14310           reportOriginalDsa(*this, DSAStack, D, DVar);
14311           continue;
14312         }
14313       }
14314 
14315       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14316       // A list item cannot appear in both a map clause and a data-sharing
14317       // attribute clause on the same construct
14318       //
14319       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14320       // A list item cannot appear in both a map clause and a data-sharing
14321       // attribute clause on the same construct unless the construct is a
14322       // combined construct.
14323       if ((LangOpts.OpenMP <= 45 &&
14324            isOpenMPTargetExecutionDirective(CurrDir)) ||
14325           CurrDir == OMPD_target) {
14326         OpenMPClauseKind ConflictKind;
14327         if (DSAStack->checkMappableExprComponentListsForDecl(
14328                 VD, /*CurrentRegionOnly=*/true,
14329                 [&ConflictKind](
14330                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
14331                     OpenMPClauseKind WhereFoundClauseKind) {
14332                   ConflictKind = WhereFoundClauseKind;
14333                   return true;
14334                 })) {
14335           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14336               << getOpenMPClauseName(OMPC_firstprivate)
14337               << getOpenMPClauseName(ConflictKind)
14338               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14339           reportOriginalDsa(*this, DSAStack, D, DVar);
14340           continue;
14341         }
14342       }
14343     }
14344 
14345     // Variably modified types are not supported for tasks.
14346     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14347         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
14348       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14349           << getOpenMPClauseName(OMPC_firstprivate) << Type
14350           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14351       bool IsDecl =
14352           !VD ||
14353           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14354       Diag(D->getLocation(),
14355            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14356           << D;
14357       continue;
14358     }
14359 
14360     Type = Type.getUnqualifiedType();
14361     VarDecl *VDPrivate =
14362         buildVarDecl(*this, ELoc, Type, D->getName(),
14363                      D->hasAttrs() ? &D->getAttrs() : nullptr,
14364                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14365     // Generate helper private variable and initialize it with the value of the
14366     // original variable. The address of the original variable is replaced by
14367     // the address of the new private variable in the CodeGen. This new variable
14368     // is not added to IdResolver, so the code in the OpenMP region uses
14369     // original variable for proper diagnostics and variable capturing.
14370     Expr *VDInitRefExpr = nullptr;
14371     // For arrays generate initializer for single element and replace it by the
14372     // original array element in CodeGen.
14373     if (Type->isArrayType()) {
14374       VarDecl *VDInit =
14375           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14376       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14377       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14378       ElemType = ElemType.getUnqualifiedType();
14379       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14380                                          ".firstprivate.temp");
14381       InitializedEntity Entity =
14382           InitializedEntity::InitializeVariable(VDInitTemp);
14383       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14384 
14385       InitializationSequence InitSeq(*this, Entity, Kind, Init);
14386       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14387       if (Result.isInvalid())
14388         VDPrivate->setInvalidDecl();
14389       else
14390         VDPrivate->setInit(Result.getAs<Expr>());
14391       // Remove temp variable declaration.
14392       Context.Deallocate(VDInitTemp);
14393     } else {
14394       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14395                                      ".firstprivate.temp");
14396       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14397                                        RefExpr->getExprLoc());
14398       AddInitializerToDecl(VDPrivate,
14399                            DefaultLvalueConversion(VDInitRefExpr).get(),
14400                            /*DirectInit=*/false);
14401     }
14402     if (VDPrivate->isInvalidDecl()) {
14403       if (IsImplicitClause) {
14404         Diag(RefExpr->getExprLoc(),
14405              diag::note_omp_task_predetermined_firstprivate_here);
14406       }
14407       continue;
14408     }
14409     CurContext->addDecl(VDPrivate);
14410     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14411         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14412         RefExpr->getExprLoc());
14413     DeclRefExpr *Ref = nullptr;
14414     if (!VD && !CurContext->isDependentContext()) {
14415       if (TopDVar.CKind == OMPC_lastprivate) {
14416         Ref = TopDVar.PrivateCopy;
14417       } else {
14418         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14419         if (!isOpenMPCapturedDecl(D))
14420           ExprCaptures.push_back(Ref->getDecl());
14421       }
14422     }
14423     if (!IsImplicitClause)
14424       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14425     Vars.push_back((VD || CurContext->isDependentContext())
14426                        ? RefExpr->IgnoreParens()
14427                        : Ref);
14428     PrivateCopies.push_back(VDPrivateRefExpr);
14429     Inits.push_back(VDInitRefExpr);
14430   }
14431 
14432   if (Vars.empty())
14433     return nullptr;
14434 
14435   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14436                                        Vars, PrivateCopies, Inits,
14437                                        buildPreInits(Context, ExprCaptures));
14438 }
14439 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14440 OMPClause *Sema::ActOnOpenMPLastprivateClause(
14441     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14442     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14443     SourceLocation LParenLoc, SourceLocation EndLoc) {
14444   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14445     assert(ColonLoc.isValid() && "Colon location must be valid.");
14446     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14447         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14448                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
14449         << getOpenMPClauseName(OMPC_lastprivate);
14450     return nullptr;
14451   }
14452 
14453   SmallVector<Expr *, 8> Vars;
14454   SmallVector<Expr *, 8> SrcExprs;
14455   SmallVector<Expr *, 8> DstExprs;
14456   SmallVector<Expr *, 8> AssignmentOps;
14457   SmallVector<Decl *, 4> ExprCaptures;
14458   SmallVector<Expr *, 4> ExprPostUpdates;
14459   for (Expr *RefExpr : VarList) {
14460     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14461     SourceLocation ELoc;
14462     SourceRange ERange;
14463     Expr *SimpleRefExpr = RefExpr;
14464     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14465     if (Res.second) {
14466       // It will be analyzed later.
14467       Vars.push_back(RefExpr);
14468       SrcExprs.push_back(nullptr);
14469       DstExprs.push_back(nullptr);
14470       AssignmentOps.push_back(nullptr);
14471     }
14472     ValueDecl *D = Res.first;
14473     if (!D)
14474       continue;
14475 
14476     QualType Type = D->getType();
14477     auto *VD = dyn_cast<VarDecl>(D);
14478 
14479     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14480     //  A variable that appears in a lastprivate clause must not have an
14481     //  incomplete type or a reference type.
14482     if (RequireCompleteType(ELoc, Type,
14483                             diag::err_omp_lastprivate_incomplete_type))
14484       continue;
14485     Type = Type.getNonReferenceType();
14486 
14487     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14488     // A variable that is privatized must not have a const-qualified type
14489     // unless it is of class type with a mutable member. This restriction does
14490     // not apply to the firstprivate clause.
14491     //
14492     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14493     // A variable that appears in a lastprivate clause must not have a
14494     // const-qualified type unless it is of class type with a mutable member.
14495     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14496       continue;
14497 
14498     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14499     // A list item that appears in a lastprivate clause with the conditional
14500     // modifier must be a scalar variable.
14501     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14502       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14503       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14504                                VarDecl::DeclarationOnly;
14505       Diag(D->getLocation(),
14506            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14507           << D;
14508       continue;
14509     }
14510 
14511     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14512     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14513     // in a Construct]
14514     //  Variables with the predetermined data-sharing attributes may not be
14515     //  listed in data-sharing attributes clauses, except for the cases
14516     //  listed below.
14517     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14518     // A list item may appear in a firstprivate or lastprivate clause but not
14519     // both.
14520     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14521     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14522         (isOpenMPDistributeDirective(CurrDir) ||
14523          DVar.CKind != OMPC_firstprivate) &&
14524         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14525       Diag(ELoc, diag::err_omp_wrong_dsa)
14526           << getOpenMPClauseName(DVar.CKind)
14527           << getOpenMPClauseName(OMPC_lastprivate);
14528       reportOriginalDsa(*this, DSAStack, D, DVar);
14529       continue;
14530     }
14531 
14532     // OpenMP [2.14.3.5, Restrictions, p.2]
14533     // A list item that is private within a parallel region, or that appears in
14534     // the reduction clause of a parallel construct, must not appear in a
14535     // lastprivate clause on a worksharing construct if any of the corresponding
14536     // worksharing regions ever binds to any of the corresponding parallel
14537     // regions.
14538     DSAStackTy::DSAVarData TopDVar = DVar;
14539     if (isOpenMPWorksharingDirective(CurrDir) &&
14540         !isOpenMPParallelDirective(CurrDir) &&
14541         !isOpenMPTeamsDirective(CurrDir)) {
14542       DVar = DSAStack->getImplicitDSA(D, true);
14543       if (DVar.CKind != OMPC_shared) {
14544         Diag(ELoc, diag::err_omp_required_access)
14545             << getOpenMPClauseName(OMPC_lastprivate)
14546             << getOpenMPClauseName(OMPC_shared);
14547         reportOriginalDsa(*this, DSAStack, D, DVar);
14548         continue;
14549       }
14550     }
14551 
14552     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14553     //  A variable of class type (or array thereof) that appears in a
14554     //  lastprivate clause requires an accessible, unambiguous default
14555     //  constructor for the class type, unless the list item is also specified
14556     //  in a firstprivate clause.
14557     //  A variable of class type (or array thereof) that appears in a
14558     //  lastprivate clause requires an accessible, unambiguous copy assignment
14559     //  operator for the class type.
14560     Type = Context.getBaseElementType(Type).getNonReferenceType();
14561     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14562                                   Type.getUnqualifiedType(), ".lastprivate.src",
14563                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
14564     DeclRefExpr *PseudoSrcExpr =
14565         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14566     VarDecl *DstVD =
14567         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14568                      D->hasAttrs() ? &D->getAttrs() : nullptr);
14569     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14570     // For arrays generate assignment operation for single element and replace
14571     // it by the original array element in CodeGen.
14572     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14573                                          PseudoDstExpr, PseudoSrcExpr);
14574     if (AssignmentOp.isInvalid())
14575       continue;
14576     AssignmentOp =
14577         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14578     if (AssignmentOp.isInvalid())
14579       continue;
14580 
14581     DeclRefExpr *Ref = nullptr;
14582     if (!VD && !CurContext->isDependentContext()) {
14583       if (TopDVar.CKind == OMPC_firstprivate) {
14584         Ref = TopDVar.PrivateCopy;
14585       } else {
14586         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14587         if (!isOpenMPCapturedDecl(D))
14588           ExprCaptures.push_back(Ref->getDecl());
14589       }
14590       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14591           (!isOpenMPCapturedDecl(D) &&
14592            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14593         ExprResult RefRes = DefaultLvalueConversion(Ref);
14594         if (!RefRes.isUsable())
14595           continue;
14596         ExprResult PostUpdateRes =
14597             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14598                        RefRes.get());
14599         if (!PostUpdateRes.isUsable())
14600           continue;
14601         ExprPostUpdates.push_back(
14602             IgnoredValueConversions(PostUpdateRes.get()).get());
14603       }
14604     }
14605     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14606     Vars.push_back((VD || CurContext->isDependentContext())
14607                        ? RefExpr->IgnoreParens()
14608                        : Ref);
14609     SrcExprs.push_back(PseudoSrcExpr);
14610     DstExprs.push_back(PseudoDstExpr);
14611     AssignmentOps.push_back(AssignmentOp.get());
14612   }
14613 
14614   if (Vars.empty())
14615     return nullptr;
14616 
14617   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14618                                       Vars, SrcExprs, DstExprs, AssignmentOps,
14619                                       LPKind, LPKindLoc, ColonLoc,
14620                                       buildPreInits(Context, ExprCaptures),
14621                                       buildPostUpdate(*this, ExprPostUpdates));
14622 }
14623 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14624 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14625                                          SourceLocation StartLoc,
14626                                          SourceLocation LParenLoc,
14627                                          SourceLocation EndLoc) {
14628   SmallVector<Expr *, 8> Vars;
14629   for (Expr *RefExpr : VarList) {
14630     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14631     SourceLocation ELoc;
14632     SourceRange ERange;
14633     Expr *SimpleRefExpr = RefExpr;
14634     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14635     if (Res.second) {
14636       // It will be analyzed later.
14637       Vars.push_back(RefExpr);
14638     }
14639     ValueDecl *D = Res.first;
14640     if (!D)
14641       continue;
14642 
14643     auto *VD = dyn_cast<VarDecl>(D);
14644     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14645     // in a Construct]
14646     //  Variables with the predetermined data-sharing attributes may not be
14647     //  listed in data-sharing attributes clauses, except for the cases
14648     //  listed below. For these exceptions only, listing a predetermined
14649     //  variable in a data-sharing attribute clause is allowed and overrides
14650     //  the variable's predetermined data-sharing attributes.
14651     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14652     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14653         DVar.RefExpr) {
14654       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14655                                           << getOpenMPClauseName(OMPC_shared);
14656       reportOriginalDsa(*this, DSAStack, D, DVar);
14657       continue;
14658     }
14659 
14660     DeclRefExpr *Ref = nullptr;
14661     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14662       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14663     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14664     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14665                        ? RefExpr->IgnoreParens()
14666                        : Ref);
14667   }
14668 
14669   if (Vars.empty())
14670     return nullptr;
14671 
14672   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14673 }
14674 
14675 namespace {
14676 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14677   DSAStackTy *Stack;
14678 
14679 public:
VisitDeclRefExpr(DeclRefExpr * E)14680   bool VisitDeclRefExpr(DeclRefExpr *E) {
14681     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14682       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14683       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14684         return false;
14685       if (DVar.CKind != OMPC_unknown)
14686         return true;
14687       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14688           VD,
14689           [](OpenMPClauseKind C, bool AppliedToPointee) {
14690             return isOpenMPPrivate(C) && !AppliedToPointee;
14691           },
14692           [](OpenMPDirectiveKind) { return true; },
14693           /*FromParent=*/true);
14694       return DVarPrivate.CKind != OMPC_unknown;
14695     }
14696     return false;
14697   }
VisitStmt(Stmt * S)14698   bool VisitStmt(Stmt *S) {
14699     for (Stmt *Child : S->children()) {
14700       if (Child && Visit(Child))
14701         return true;
14702     }
14703     return false;
14704   }
DSARefChecker(DSAStackTy * S)14705   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14706 };
14707 } // namespace
14708 
14709 namespace {
14710 // Transform MemberExpression for specified FieldDecl of current class to
14711 // DeclRefExpr to specified OMPCapturedExprDecl.
14712 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14713   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14714   ValueDecl *Field = nullptr;
14715   DeclRefExpr *CapturedExpr = nullptr;
14716 
14717 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)14718   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14719       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14720 
TransformMemberExpr(MemberExpr * E)14721   ExprResult TransformMemberExpr(MemberExpr *E) {
14722     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14723         E->getMemberDecl() == Field) {
14724       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14725       return CapturedExpr;
14726     }
14727     return BaseTransform::TransformMemberExpr(E);
14728   }
getCapturedExpr()14729   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14730 };
14731 } // namespace
14732 
14733 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)14734 static T filterLookupForUDReductionAndMapper(
14735     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14736   for (U &Set : Lookups) {
14737     for (auto *D : Set) {
14738       if (T Res = Gen(cast<ValueDecl>(D)))
14739         return Res;
14740     }
14741   }
14742   return T();
14743 }
14744 
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)14745 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14746   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
14747 
14748   for (auto RD : D->redecls()) {
14749     // Don't bother with extra checks if we already know this one isn't visible.
14750     if (RD == D)
14751       continue;
14752 
14753     auto ND = cast<NamedDecl>(RD);
14754     if (LookupResult::isVisible(SemaRef, ND))
14755       return ND;
14756   }
14757 
14758   return nullptr;
14759 }
14760 
14761 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)14762 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14763                         SourceLocation Loc, QualType Ty,
14764                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14765   // Find all of the associated namespaces and classes based on the
14766   // arguments we have.
14767   Sema::AssociatedNamespaceSet AssociatedNamespaces;
14768   Sema::AssociatedClassSet AssociatedClasses;
14769   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14770   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14771                                              AssociatedClasses);
14772 
14773   // C++ [basic.lookup.argdep]p3:
14774   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
14775   //   and let Y be the lookup set produced by argument dependent
14776   //   lookup (defined as follows). If X contains [...] then Y is
14777   //   empty. Otherwise Y is the set of declarations found in the
14778   //   namespaces associated with the argument types as described
14779   //   below. The set of declarations found by the lookup of the name
14780   //   is the union of X and Y.
14781   //
14782   // Here, we compute Y and add its members to the overloaded
14783   // candidate set.
14784   for (auto *NS : AssociatedNamespaces) {
14785     //   When considering an associated namespace, the lookup is the
14786     //   same as the lookup performed when the associated namespace is
14787     //   used as a qualifier (3.4.3.2) except that:
14788     //
14789     //     -- Any using-directives in the associated namespace are
14790     //        ignored.
14791     //
14792     //     -- Any namespace-scope friend functions declared in
14793     //        associated classes are visible within their respective
14794     //        namespaces even if they are not visible during an ordinary
14795     //        lookup (11.4).
14796     DeclContext::lookup_result R = NS->lookup(Id.getName());
14797     for (auto *D : R) {
14798       auto *Underlying = D;
14799       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14800         Underlying = USD->getTargetDecl();
14801 
14802       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14803           !isa<OMPDeclareMapperDecl>(Underlying))
14804         continue;
14805 
14806       if (!SemaRef.isVisible(D)) {
14807         D = findAcceptableDecl(SemaRef, D);
14808         if (!D)
14809           continue;
14810         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14811           Underlying = USD->getTargetDecl();
14812       }
14813       Lookups.emplace_back();
14814       Lookups.back().addDecl(Underlying);
14815     }
14816   }
14817 }
14818 
14819 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)14820 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14821                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14822                          const DeclarationNameInfo &ReductionId, QualType Ty,
14823                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14824   if (ReductionIdScopeSpec.isInvalid())
14825     return ExprError();
14826   SmallVector<UnresolvedSet<8>, 4> Lookups;
14827   if (S) {
14828     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14829     Lookup.suppressDiagnostics();
14830     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14831       NamedDecl *D = Lookup.getRepresentativeDecl();
14832       do {
14833         S = S->getParent();
14834       } while (S && !S->isDeclScope(D));
14835       if (S)
14836         S = S->getParent();
14837       Lookups.emplace_back();
14838       Lookups.back().append(Lookup.begin(), Lookup.end());
14839       Lookup.clear();
14840     }
14841   } else if (auto *ULE =
14842                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14843     Lookups.push_back(UnresolvedSet<8>());
14844     Decl *PrevD = nullptr;
14845     for (NamedDecl *D : ULE->decls()) {
14846       if (D == PrevD)
14847         Lookups.push_back(UnresolvedSet<8>());
14848       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14849         Lookups.back().addDecl(DRD);
14850       PrevD = D;
14851     }
14852   }
14853   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14854       Ty->isInstantiationDependentType() ||
14855       Ty->containsUnexpandedParameterPack() ||
14856       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14857         return !D->isInvalidDecl() &&
14858                (D->getType()->isDependentType() ||
14859                 D->getType()->isInstantiationDependentType() ||
14860                 D->getType()->containsUnexpandedParameterPack());
14861       })) {
14862     UnresolvedSet<8> ResSet;
14863     for (const UnresolvedSet<8> &Set : Lookups) {
14864       if (Set.empty())
14865         continue;
14866       ResSet.append(Set.begin(), Set.end());
14867       // The last item marks the end of all declarations at the specified scope.
14868       ResSet.addDecl(Set[Set.size() - 1]);
14869     }
14870     return UnresolvedLookupExpr::Create(
14871         SemaRef.Context, /*NamingClass=*/nullptr,
14872         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14873         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14874   }
14875   // Lookup inside the classes.
14876   // C++ [over.match.oper]p3:
14877   //   For a unary operator @ with an operand of a type whose
14878   //   cv-unqualified version is T1, and for a binary operator @ with
14879   //   a left operand of a type whose cv-unqualified version is T1 and
14880   //   a right operand of a type whose cv-unqualified version is T2,
14881   //   three sets of candidate functions, designated member
14882   //   candidates, non-member candidates and built-in candidates, are
14883   //   constructed as follows:
14884   //     -- If T1 is a complete class type or a class currently being
14885   //        defined, the set of member candidates is the result of the
14886   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14887   //        the set of member candidates is empty.
14888   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14889   Lookup.suppressDiagnostics();
14890   if (const auto *TyRec = Ty->getAs<RecordType>()) {
14891     // Complete the type if it can be completed.
14892     // If the type is neither complete nor being defined, bail out now.
14893     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14894         TyRec->getDecl()->getDefinition()) {
14895       Lookup.clear();
14896       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14897       if (Lookup.empty()) {
14898         Lookups.emplace_back();
14899         Lookups.back().append(Lookup.begin(), Lookup.end());
14900       }
14901     }
14902   }
14903   // Perform ADL.
14904   if (SemaRef.getLangOpts().CPlusPlus)
14905     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14906   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14907           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14908             if (!D->isInvalidDecl() &&
14909                 SemaRef.Context.hasSameType(D->getType(), Ty))
14910               return D;
14911             return nullptr;
14912           }))
14913     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14914                                     VK_LValue, Loc);
14915   if (SemaRef.getLangOpts().CPlusPlus) {
14916     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14917             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14918               if (!D->isInvalidDecl() &&
14919                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14920                   !Ty.isMoreQualifiedThan(D->getType()))
14921                 return D;
14922               return nullptr;
14923             })) {
14924       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14925                          /*DetectVirtual=*/false);
14926       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14927         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14928                 VD->getType().getUnqualifiedType()))) {
14929           if (SemaRef.CheckBaseClassAccess(
14930                   Loc, VD->getType(), Ty, Paths.front(),
14931                   /*DiagID=*/0) != Sema::AR_inaccessible) {
14932             SemaRef.BuildBasePathArray(Paths, BasePath);
14933             return SemaRef.BuildDeclRefExpr(
14934                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14935           }
14936         }
14937       }
14938     }
14939   }
14940   if (ReductionIdScopeSpec.isSet()) {
14941     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14942         << Ty << Range;
14943     return ExprError();
14944   }
14945   return ExprEmpty();
14946 }
14947 
14948 namespace {
14949 /// Data for the reduction-based clauses.
14950 struct ReductionData {
14951   /// List of original reduction items.
14952   SmallVector<Expr *, 8> Vars;
14953   /// List of private copies of the reduction items.
14954   SmallVector<Expr *, 8> Privates;
14955   /// LHS expressions for the reduction_op expressions.
14956   SmallVector<Expr *, 8> LHSs;
14957   /// RHS expressions for the reduction_op expressions.
14958   SmallVector<Expr *, 8> RHSs;
14959   /// Reduction operation expression.
14960   SmallVector<Expr *, 8> ReductionOps;
14961   /// inscan copy operation expressions.
14962   SmallVector<Expr *, 8> InscanCopyOps;
14963   /// inscan copy temp array expressions for prefix sums.
14964   SmallVector<Expr *, 8> InscanCopyArrayTemps;
14965   /// inscan copy temp array element expressions for prefix sums.
14966   SmallVector<Expr *, 8> InscanCopyArrayElems;
14967   /// Taskgroup descriptors for the corresponding reduction items in
14968   /// in_reduction clauses.
14969   SmallVector<Expr *, 8> TaskgroupDescriptors;
14970   /// List of captures for clause.
14971   SmallVector<Decl *, 4> ExprCaptures;
14972   /// List of postupdate expressions.
14973   SmallVector<Expr *, 4> ExprPostUpdates;
14974   /// Reduction modifier.
14975   unsigned RedModifier = 0;
14976   ReductionData() = delete;
14977   /// Reserves required memory for the reduction data.
ReductionData__anon5b5425d04811::ReductionData14978   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14979     Vars.reserve(Size);
14980     Privates.reserve(Size);
14981     LHSs.reserve(Size);
14982     RHSs.reserve(Size);
14983     ReductionOps.reserve(Size);
14984     if (RedModifier == OMPC_REDUCTION_inscan) {
14985       InscanCopyOps.reserve(Size);
14986       InscanCopyArrayTemps.reserve(Size);
14987       InscanCopyArrayElems.reserve(Size);
14988     }
14989     TaskgroupDescriptors.reserve(Size);
14990     ExprCaptures.reserve(Size);
14991     ExprPostUpdates.reserve(Size);
14992   }
14993   /// Stores reduction item and reduction operation only (required for dependent
14994   /// reduction item).
push__anon5b5425d04811::ReductionData14995   void push(Expr *Item, Expr *ReductionOp) {
14996     Vars.emplace_back(Item);
14997     Privates.emplace_back(nullptr);
14998     LHSs.emplace_back(nullptr);
14999     RHSs.emplace_back(nullptr);
15000     ReductionOps.emplace_back(ReductionOp);
15001     TaskgroupDescriptors.emplace_back(nullptr);
15002     if (RedModifier == OMPC_REDUCTION_inscan) {
15003       InscanCopyOps.push_back(nullptr);
15004       InscanCopyArrayTemps.push_back(nullptr);
15005       InscanCopyArrayElems.push_back(nullptr);
15006     }
15007   }
15008   /// Stores reduction data.
push__anon5b5425d04811::ReductionData15009   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
15010             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
15011             Expr *CopyArrayElem) {
15012     Vars.emplace_back(Item);
15013     Privates.emplace_back(Private);
15014     LHSs.emplace_back(LHS);
15015     RHSs.emplace_back(RHS);
15016     ReductionOps.emplace_back(ReductionOp);
15017     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
15018     if (RedModifier == OMPC_REDUCTION_inscan) {
15019       InscanCopyOps.push_back(CopyOp);
15020       InscanCopyArrayTemps.push_back(CopyArrayTemp);
15021       InscanCopyArrayElems.push_back(CopyArrayElem);
15022     } else {
15023       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
15024              CopyArrayElem == nullptr &&
15025              "Copy operation must be used for inscan reductions only.");
15026     }
15027   }
15028 };
15029 } // namespace
15030 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)15031 static bool checkOMPArraySectionConstantForReduction(
15032     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
15033     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
15034   const Expr *Length = OASE->getLength();
15035   if (Length == nullptr) {
15036     // For array sections of the form [1:] or [:], we would need to analyze
15037     // the lower bound...
15038     if (OASE->getColonLocFirst().isValid())
15039       return false;
15040 
15041     // This is an array subscript which has implicit length 1!
15042     SingleElement = true;
15043     ArraySizes.push_back(llvm::APSInt::get(1));
15044   } else {
15045     Expr::EvalResult Result;
15046     if (!Length->EvaluateAsInt(Result, Context))
15047       return false;
15048 
15049     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15050     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
15051     ArraySizes.push_back(ConstantLengthValue);
15052   }
15053 
15054   // Get the base of this array section and walk up from there.
15055   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
15056 
15057   // We require length = 1 for all array sections except the right-most to
15058   // guarantee that the memory region is contiguous and has no holes in it.
15059   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
15060     Length = TempOASE->getLength();
15061     if (Length == nullptr) {
15062       // For array sections of the form [1:] or [:], we would need to analyze
15063       // the lower bound...
15064       if (OASE->getColonLocFirst().isValid())
15065         return false;
15066 
15067       // This is an array subscript which has implicit length 1!
15068       ArraySizes.push_back(llvm::APSInt::get(1));
15069     } else {
15070       Expr::EvalResult Result;
15071       if (!Length->EvaluateAsInt(Result, Context))
15072         return false;
15073 
15074       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
15075       if (ConstantLengthValue.getSExtValue() != 1)
15076         return false;
15077 
15078       ArraySizes.push_back(ConstantLengthValue);
15079     }
15080     Base = TempOASE->getBase()->IgnoreParenImpCasts();
15081   }
15082 
15083   // If we have a single element, we don't need to add the implicit lengths.
15084   if (!SingleElement) {
15085     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
15086       // Has implicit length 1!
15087       ArraySizes.push_back(llvm::APSInt::get(1));
15088       Base = TempASE->getBase()->IgnoreParenImpCasts();
15089     }
15090   }
15091 
15092   // This array section can be privatized as a single value or as a constant
15093   // sized array.
15094   return true;
15095 }
15096 
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)15097 static bool actOnOMPReductionKindClause(
15098     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
15099     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15100     SourceLocation ColonLoc, SourceLocation EndLoc,
15101     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15102     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
15103   DeclarationName DN = ReductionId.getName();
15104   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
15105   BinaryOperatorKind BOK = BO_Comma;
15106 
15107   ASTContext &Context = S.Context;
15108   // OpenMP [2.14.3.6, reduction clause]
15109   // C
15110   // reduction-identifier is either an identifier or one of the following
15111   // operators: +, -, *,  &, |, ^, && and ||
15112   // C++
15113   // reduction-identifier is either an id-expression or one of the following
15114   // operators: +, -, *, &, |, ^, && and ||
15115   switch (OOK) {
15116   case OO_Plus:
15117   case OO_Minus:
15118     BOK = BO_Add;
15119     break;
15120   case OO_Star:
15121     BOK = BO_Mul;
15122     break;
15123   case OO_Amp:
15124     BOK = BO_And;
15125     break;
15126   case OO_Pipe:
15127     BOK = BO_Or;
15128     break;
15129   case OO_Caret:
15130     BOK = BO_Xor;
15131     break;
15132   case OO_AmpAmp:
15133     BOK = BO_LAnd;
15134     break;
15135   case OO_PipePipe:
15136     BOK = BO_LOr;
15137     break;
15138   case OO_New:
15139   case OO_Delete:
15140   case OO_Array_New:
15141   case OO_Array_Delete:
15142   case OO_Slash:
15143   case OO_Percent:
15144   case OO_Tilde:
15145   case OO_Exclaim:
15146   case OO_Equal:
15147   case OO_Less:
15148   case OO_Greater:
15149   case OO_LessEqual:
15150   case OO_GreaterEqual:
15151   case OO_PlusEqual:
15152   case OO_MinusEqual:
15153   case OO_StarEqual:
15154   case OO_SlashEqual:
15155   case OO_PercentEqual:
15156   case OO_CaretEqual:
15157   case OO_AmpEqual:
15158   case OO_PipeEqual:
15159   case OO_LessLess:
15160   case OO_GreaterGreater:
15161   case OO_LessLessEqual:
15162   case OO_GreaterGreaterEqual:
15163   case OO_EqualEqual:
15164   case OO_ExclaimEqual:
15165   case OO_Spaceship:
15166   case OO_PlusPlus:
15167   case OO_MinusMinus:
15168   case OO_Comma:
15169   case OO_ArrowStar:
15170   case OO_Arrow:
15171   case OO_Call:
15172   case OO_Subscript:
15173   case OO_Conditional:
15174   case OO_Coawait:
15175   case NUM_OVERLOADED_OPERATORS:
15176     llvm_unreachable("Unexpected reduction identifier");
15177   case OO_None:
15178     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15179       if (II->isStr("max"))
15180         BOK = BO_GT;
15181       else if (II->isStr("min"))
15182         BOK = BO_LT;
15183     }
15184     break;
15185   }
15186   SourceRange ReductionIdRange;
15187   if (ReductionIdScopeSpec.isValid())
15188     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15189   else
15190     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15191   ReductionIdRange.setEnd(ReductionId.getEndLoc());
15192 
15193   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15194   bool FirstIter = true;
15195   for (Expr *RefExpr : VarList) {
15196     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
15197     // OpenMP [2.1, C/C++]
15198     //  A list item is a variable or array section, subject to the restrictions
15199     //  specified in Section 2.4 on page 42 and in each of the sections
15200     // describing clauses and directives for which a list appears.
15201     // OpenMP  [2.14.3.3, Restrictions, p.1]
15202     //  A variable that is part of another variable (as an array or
15203     //  structure element) cannot appear in a private clause.
15204     if (!FirstIter && IR != ER)
15205       ++IR;
15206     FirstIter = false;
15207     SourceLocation ELoc;
15208     SourceRange ERange;
15209     Expr *SimpleRefExpr = RefExpr;
15210     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15211                               /*AllowArraySection=*/true);
15212     if (Res.second) {
15213       // Try to find 'declare reduction' corresponding construct before using
15214       // builtin/overloaded operators.
15215       QualType Type = Context.DependentTy;
15216       CXXCastPath BasePath;
15217       ExprResult DeclareReductionRef = buildDeclareReductionRef(
15218           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15219           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15220       Expr *ReductionOp = nullptr;
15221       if (S.CurContext->isDependentContext() &&
15222           (DeclareReductionRef.isUnset() ||
15223            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15224         ReductionOp = DeclareReductionRef.get();
15225       // It will be analyzed later.
15226       RD.push(RefExpr, ReductionOp);
15227     }
15228     ValueDecl *D = Res.first;
15229     if (!D)
15230       continue;
15231 
15232     Expr *TaskgroupDescriptor = nullptr;
15233     QualType Type;
15234     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15235     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15236     if (ASE) {
15237       Type = ASE->getType().getNonReferenceType();
15238     } else if (OASE) {
15239       QualType BaseType =
15240           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15241       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15242         Type = ATy->getElementType();
15243       else
15244         Type = BaseType->getPointeeType();
15245       Type = Type.getNonReferenceType();
15246     } else {
15247       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15248     }
15249     auto *VD = dyn_cast<VarDecl>(D);
15250 
15251     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15252     //  A variable that appears in a private clause must not have an incomplete
15253     //  type or a reference type.
15254     if (S.RequireCompleteType(ELoc, D->getType(),
15255                               diag::err_omp_reduction_incomplete_type))
15256       continue;
15257     // OpenMP [2.14.3.6, reduction clause, Restrictions]
15258     // A list item that appears in a reduction clause must not be
15259     // const-qualified.
15260     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15261                                   /*AcceptIfMutable*/ false, ASE || OASE))
15262       continue;
15263 
15264     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15265     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15266     //  If a list-item is a reference type then it must bind to the same object
15267     //  for all threads of the team.
15268     if (!ASE && !OASE) {
15269       if (VD) {
15270         VarDecl *VDDef = VD->getDefinition();
15271         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15272           DSARefChecker Check(Stack);
15273           if (Check.Visit(VDDef->getInit())) {
15274             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15275                 << getOpenMPClauseName(ClauseKind) << ERange;
15276             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15277             continue;
15278           }
15279         }
15280       }
15281 
15282       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15283       // in a Construct]
15284       //  Variables with the predetermined data-sharing attributes may not be
15285       //  listed in data-sharing attributes clauses, except for the cases
15286       //  listed below. For these exceptions only, listing a predetermined
15287       //  variable in a data-sharing attribute clause is allowed and overrides
15288       //  the variable's predetermined data-sharing attributes.
15289       // OpenMP [2.14.3.6, Restrictions, p.3]
15290       //  Any number of reduction clauses can be specified on the directive,
15291       //  but a list item can appear only once in the reduction clauses for that
15292       //  directive.
15293       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15294       if (DVar.CKind == OMPC_reduction) {
15295         S.Diag(ELoc, diag::err_omp_once_referenced)
15296             << getOpenMPClauseName(ClauseKind);
15297         if (DVar.RefExpr)
15298           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15299         continue;
15300       }
15301       if (DVar.CKind != OMPC_unknown) {
15302         S.Diag(ELoc, diag::err_omp_wrong_dsa)
15303             << getOpenMPClauseName(DVar.CKind)
15304             << getOpenMPClauseName(OMPC_reduction);
15305         reportOriginalDsa(S, Stack, D, DVar);
15306         continue;
15307       }
15308 
15309       // OpenMP [2.14.3.6, Restrictions, p.1]
15310       //  A list item that appears in a reduction clause of a worksharing
15311       //  construct must be shared in the parallel regions to which any of the
15312       //  worksharing regions arising from the worksharing construct bind.
15313       if (isOpenMPWorksharingDirective(CurrDir) &&
15314           !isOpenMPParallelDirective(CurrDir) &&
15315           !isOpenMPTeamsDirective(CurrDir)) {
15316         DVar = Stack->getImplicitDSA(D, true);
15317         if (DVar.CKind != OMPC_shared) {
15318           S.Diag(ELoc, diag::err_omp_required_access)
15319               << getOpenMPClauseName(OMPC_reduction)
15320               << getOpenMPClauseName(OMPC_shared);
15321           reportOriginalDsa(S, Stack, D, DVar);
15322           continue;
15323         }
15324       }
15325     } else {
15326       // Threadprivates cannot be shared between threads, so dignose if the base
15327       // is a threadprivate variable.
15328       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15329       if (DVar.CKind == OMPC_threadprivate) {
15330         S.Diag(ELoc, diag::err_omp_wrong_dsa)
15331             << getOpenMPClauseName(DVar.CKind)
15332             << getOpenMPClauseName(OMPC_reduction);
15333         reportOriginalDsa(S, Stack, D, DVar);
15334         continue;
15335       }
15336     }
15337 
15338     // Try to find 'declare reduction' corresponding construct before using
15339     // builtin/overloaded operators.
15340     CXXCastPath BasePath;
15341     ExprResult DeclareReductionRef = buildDeclareReductionRef(
15342         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15343         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15344     if (DeclareReductionRef.isInvalid())
15345       continue;
15346     if (S.CurContext->isDependentContext() &&
15347         (DeclareReductionRef.isUnset() ||
15348          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15349       RD.push(RefExpr, DeclareReductionRef.get());
15350       continue;
15351     }
15352     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15353       // Not allowed reduction identifier is found.
15354       S.Diag(ReductionId.getBeginLoc(),
15355              diag::err_omp_unknown_reduction_identifier)
15356           << Type << ReductionIdRange;
15357       continue;
15358     }
15359 
15360     // OpenMP [2.14.3.6, reduction clause, Restrictions]
15361     // The type of a list item that appears in a reduction clause must be valid
15362     // for the reduction-identifier. For a max or min reduction in C, the type
15363     // of the list item must be an allowed arithmetic data type: char, int,
15364     // float, double, or _Bool, possibly modified with long, short, signed, or
15365     // unsigned. For a max or min reduction in C++, the type of the list item
15366     // must be an allowed arithmetic data type: char, wchar_t, int, float,
15367     // double, or bool, possibly modified with long, short, signed, or unsigned.
15368     if (DeclareReductionRef.isUnset()) {
15369       if ((BOK == BO_GT || BOK == BO_LT) &&
15370           !(Type->isScalarType() ||
15371             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15372         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15373             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15374         if (!ASE && !OASE) {
15375           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15376                                    VarDecl::DeclarationOnly;
15377           S.Diag(D->getLocation(),
15378                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15379               << D;
15380         }
15381         continue;
15382       }
15383       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15384           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15385         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15386             << getOpenMPClauseName(ClauseKind);
15387         if (!ASE && !OASE) {
15388           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15389                                    VarDecl::DeclarationOnly;
15390           S.Diag(D->getLocation(),
15391                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15392               << D;
15393         }
15394         continue;
15395       }
15396     }
15397 
15398     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15399     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15400                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
15401     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15402                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
15403     QualType PrivateTy = Type;
15404 
15405     // Try if we can determine constant lengths for all array sections and avoid
15406     // the VLA.
15407     bool ConstantLengthOASE = false;
15408     if (OASE) {
15409       bool SingleElement;
15410       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15411       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15412           Context, OASE, SingleElement, ArraySizes);
15413 
15414       // If we don't have a single element, we must emit a constant array type.
15415       if (ConstantLengthOASE && !SingleElement) {
15416         for (llvm::APSInt &Size : ArraySizes)
15417           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15418                                                    ArrayType::Normal,
15419                                                    /*IndexTypeQuals=*/0);
15420       }
15421     }
15422 
15423     if ((OASE && !ConstantLengthOASE) ||
15424         (!OASE && !ASE &&
15425          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15426       if (!Context.getTargetInfo().isVLASupported()) {
15427         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15428           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15429           S.Diag(ELoc, diag::note_vla_unsupported);
15430           continue;
15431         } else {
15432           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15433           S.targetDiag(ELoc, diag::note_vla_unsupported);
15434         }
15435       }
15436       // For arrays/array sections only:
15437       // Create pseudo array type for private copy. The size for this array will
15438       // be generated during codegen.
15439       // For array subscripts or single variables Private Ty is the same as Type
15440       // (type of the variable or single array element).
15441       PrivateTy = Context.getVariableArrayType(
15442           Type,
15443           new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15444           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15445     } else if (!ASE && !OASE &&
15446                Context.getAsArrayType(D->getType().getNonReferenceType())) {
15447       PrivateTy = D->getType().getNonReferenceType();
15448     }
15449     // Private copy.
15450     VarDecl *PrivateVD =
15451         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15452                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15453                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15454     // Add initializer for private variable.
15455     Expr *Init = nullptr;
15456     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15457     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15458     if (DeclareReductionRef.isUsable()) {
15459       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15460       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15461       if (DRD->getInitializer()) {
15462         S.ActOnUninitializedDecl(PrivateVD);
15463         Init = DRDRef;
15464         RHSVD->setInit(DRDRef);
15465         RHSVD->setInitStyle(VarDecl::CallInit);
15466       }
15467     } else {
15468       switch (BOK) {
15469       case BO_Add:
15470       case BO_Xor:
15471       case BO_Or:
15472       case BO_LOr:
15473         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15474         if (Type->isScalarType() || Type->isAnyComplexType())
15475           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15476         break;
15477       case BO_Mul:
15478       case BO_LAnd:
15479         if (Type->isScalarType() || Type->isAnyComplexType()) {
15480           // '*' and '&&' reduction ops - initializer is '1'.
15481           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15482         }
15483         break;
15484       case BO_And: {
15485         // '&' reduction op - initializer is '~0'.
15486         QualType OrigType = Type;
15487         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15488           Type = ComplexTy->getElementType();
15489         if (Type->isRealFloatingType()) {
15490           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15491               Context.getFloatTypeSemantics(Type),
15492               Context.getTypeSize(Type));
15493           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15494                                          Type, ELoc);
15495         } else if (Type->isScalarType()) {
15496           uint64_t Size = Context.getTypeSize(Type);
15497           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15498           llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15499           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15500         }
15501         if (Init && OrigType->isAnyComplexType()) {
15502           // Init = 0xFFFF + 0xFFFFi;
15503           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15504           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15505         }
15506         Type = OrigType;
15507         break;
15508       }
15509       case BO_LT:
15510       case BO_GT: {
15511         // 'min' reduction op - initializer is 'Largest representable number in
15512         // the reduction list item type'.
15513         // 'max' reduction op - initializer is 'Least representable number in
15514         // the reduction list item type'.
15515         if (Type->isIntegerType() || Type->isPointerType()) {
15516           bool IsSigned = Type->hasSignedIntegerRepresentation();
15517           uint64_t Size = Context.getTypeSize(Type);
15518           QualType IntTy =
15519               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15520           llvm::APInt InitValue =
15521               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15522                                         : llvm::APInt::getMinValue(Size)
15523                              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15524                                         : llvm::APInt::getMaxValue(Size);
15525           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15526           if (Type->isPointerType()) {
15527             // Cast to pointer type.
15528             ExprResult CastExpr = S.BuildCStyleCastExpr(
15529                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15530             if (CastExpr.isInvalid())
15531               continue;
15532             Init = CastExpr.get();
15533           }
15534         } else if (Type->isRealFloatingType()) {
15535           llvm::APFloat InitValue = llvm::APFloat::getLargest(
15536               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15537           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15538                                          Type, ELoc);
15539         }
15540         break;
15541       }
15542       case BO_PtrMemD:
15543       case BO_PtrMemI:
15544       case BO_MulAssign:
15545       case BO_Div:
15546       case BO_Rem:
15547       case BO_Sub:
15548       case BO_Shl:
15549       case BO_Shr:
15550       case BO_LE:
15551       case BO_GE:
15552       case BO_EQ:
15553       case BO_NE:
15554       case BO_Cmp:
15555       case BO_AndAssign:
15556       case BO_XorAssign:
15557       case BO_OrAssign:
15558       case BO_Assign:
15559       case BO_AddAssign:
15560       case BO_SubAssign:
15561       case BO_DivAssign:
15562       case BO_RemAssign:
15563       case BO_ShlAssign:
15564       case BO_ShrAssign:
15565       case BO_Comma:
15566         llvm_unreachable("Unexpected reduction operation");
15567       }
15568     }
15569     if (Init && DeclareReductionRef.isUnset()) {
15570       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15571       // Store initializer for single element in private copy. Will be used
15572       // during codegen.
15573       PrivateVD->setInit(RHSVD->getInit());
15574       PrivateVD->setInitStyle(RHSVD->getInitStyle());
15575     } else if (!Init) {
15576       S.ActOnUninitializedDecl(RHSVD);
15577       // Store initializer for single element in private copy. Will be used
15578       // during codegen.
15579       PrivateVD->setInit(RHSVD->getInit());
15580       PrivateVD->setInitStyle(RHSVD->getInitStyle());
15581     }
15582     if (RHSVD->isInvalidDecl())
15583       continue;
15584     if (!RHSVD->hasInit() &&
15585         (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15586       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15587           << Type << ReductionIdRange;
15588       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15589                                VarDecl::DeclarationOnly;
15590       S.Diag(D->getLocation(),
15591              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15592           << D;
15593       continue;
15594     }
15595     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15596     ExprResult ReductionOp;
15597     if (DeclareReductionRef.isUsable()) {
15598       QualType RedTy = DeclareReductionRef.get()->getType();
15599       QualType PtrRedTy = Context.getPointerType(RedTy);
15600       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15601       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15602       if (!BasePath.empty()) {
15603         LHS = S.DefaultLvalueConversion(LHS.get());
15604         RHS = S.DefaultLvalueConversion(RHS.get());
15605         LHS = ImplicitCastExpr::Create(
15606             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
15607             LHS.get()->getValueKind(), FPOptionsOverride());
15608         RHS = ImplicitCastExpr::Create(
15609             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
15610             RHS.get()->getValueKind(), FPOptionsOverride());
15611       }
15612       FunctionProtoType::ExtProtoInfo EPI;
15613       QualType Params[] = {PtrRedTy, PtrRedTy};
15614       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15615       auto *OVE = new (Context) OpaqueValueExpr(
15616           ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15617           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15618       Expr *Args[] = {LHS.get(), RHS.get()};
15619       ReductionOp =
15620           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15621                            S.CurFPFeatureOverrides());
15622     } else {
15623       ReductionOp = S.BuildBinOp(
15624           Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15625       if (ReductionOp.isUsable()) {
15626         if (BOK != BO_LT && BOK != BO_GT) {
15627           ReductionOp =
15628               S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15629                            BO_Assign, LHSDRE, ReductionOp.get());
15630         } else {
15631           auto *ConditionalOp = new (Context)
15632               ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15633                                   Type, VK_LValue, OK_Ordinary);
15634           ReductionOp =
15635               S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15636                            BO_Assign, LHSDRE, ConditionalOp);
15637         }
15638         if (ReductionOp.isUsable())
15639           ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15640                                               /*DiscardedValue*/ false);
15641       }
15642       if (!ReductionOp.isUsable())
15643         continue;
15644     }
15645 
15646     // Add copy operations for inscan reductions.
15647     // LHS = RHS;
15648     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15649     if (ClauseKind == OMPC_reduction &&
15650         RD.RedModifier == OMPC_REDUCTION_inscan) {
15651       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15652       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15653                                RHS.get());
15654       if (!CopyOpRes.isUsable())
15655         continue;
15656       CopyOpRes =
15657           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15658       if (!CopyOpRes.isUsable())
15659         continue;
15660       // For simd directive and simd-based directives in simd mode no need to
15661       // construct temp array, need just a single temp element.
15662       if (Stack->getCurrentDirective() == OMPD_simd ||
15663           (S.getLangOpts().OpenMPSimd &&
15664            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15665         VarDecl *TempArrayVD =
15666             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15667                          D->hasAttrs() ? &D->getAttrs() : nullptr);
15668         // Add a constructor to the temp decl.
15669         S.ActOnUninitializedDecl(TempArrayVD);
15670         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15671       } else {
15672         // Build temp array for prefix sum.
15673         auto *Dim = new (S.Context)
15674             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15675         QualType ArrayTy =
15676             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15677                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
15678         VarDecl *TempArrayVD =
15679             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15680                          D->hasAttrs() ? &D->getAttrs() : nullptr);
15681         // Add a constructor to the temp decl.
15682         S.ActOnUninitializedDecl(TempArrayVD);
15683         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15684         TempArrayElem =
15685             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15686         auto *Idx = new (S.Context)
15687             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15688         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15689                                                           ELoc, Idx, ELoc);
15690       }
15691     }
15692 
15693     // OpenMP [2.15.4.6, Restrictions, p.2]
15694     // A list item that appears in an in_reduction clause of a task construct
15695     // must appear in a task_reduction clause of a construct associated with a
15696     // taskgroup region that includes the participating task in its taskgroup
15697     // set. The construct associated with the innermost region that meets this
15698     // condition must specify the same reduction-identifier as the in_reduction
15699     // clause.
15700     if (ClauseKind == OMPC_in_reduction) {
15701       SourceRange ParentSR;
15702       BinaryOperatorKind ParentBOK;
15703       const Expr *ParentReductionOp = nullptr;
15704       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15705       DSAStackTy::DSAVarData ParentBOKDSA =
15706           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15707                                                   ParentBOKTD);
15708       DSAStackTy::DSAVarData ParentReductionOpDSA =
15709           Stack->getTopMostTaskgroupReductionData(
15710               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15711       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15712       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15713       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15714           (DeclareReductionRef.isUsable() && IsParentBOK) ||
15715           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15716         bool EmitError = true;
15717         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15718           llvm::FoldingSetNodeID RedId, ParentRedId;
15719           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15720           DeclareReductionRef.get()->Profile(RedId, Context,
15721                                              /*Canonical=*/true);
15722           EmitError = RedId != ParentRedId;
15723         }
15724         if (EmitError) {
15725           S.Diag(ReductionId.getBeginLoc(),
15726                  diag::err_omp_reduction_identifier_mismatch)
15727               << ReductionIdRange << RefExpr->getSourceRange();
15728           S.Diag(ParentSR.getBegin(),
15729                  diag::note_omp_previous_reduction_identifier)
15730               << ParentSR
15731               << (IsParentBOK ? ParentBOKDSA.RefExpr
15732                               : ParentReductionOpDSA.RefExpr)
15733                      ->getSourceRange();
15734           continue;
15735         }
15736       }
15737       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15738     }
15739 
15740     DeclRefExpr *Ref = nullptr;
15741     Expr *VarsExpr = RefExpr->IgnoreParens();
15742     if (!VD && !S.CurContext->isDependentContext()) {
15743       if (ASE || OASE) {
15744         TransformExprToCaptures RebuildToCapture(S, D);
15745         VarsExpr =
15746             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15747         Ref = RebuildToCapture.getCapturedExpr();
15748       } else {
15749         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15750       }
15751       if (!S.isOpenMPCapturedDecl(D)) {
15752         RD.ExprCaptures.emplace_back(Ref->getDecl());
15753         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15754           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15755           if (!RefRes.isUsable())
15756             continue;
15757           ExprResult PostUpdateRes =
15758               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15759                            RefRes.get());
15760           if (!PostUpdateRes.isUsable())
15761             continue;
15762           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15763               Stack->getCurrentDirective() == OMPD_taskgroup) {
15764             S.Diag(RefExpr->getExprLoc(),
15765                    diag::err_omp_reduction_non_addressable_expression)
15766                 << RefExpr->getSourceRange();
15767             continue;
15768           }
15769           RD.ExprPostUpdates.emplace_back(
15770               S.IgnoredValueConversions(PostUpdateRes.get()).get());
15771         }
15772       }
15773     }
15774     // All reduction items are still marked as reduction (to do not increase
15775     // code base size).
15776     unsigned Modifier = RD.RedModifier;
15777     // Consider task_reductions as reductions with task modifier. Required for
15778     // correct analysis of in_reduction clauses.
15779     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15780       Modifier = OMPC_REDUCTION_task;
15781     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
15782                   ASE || OASE);
15783     if (Modifier == OMPC_REDUCTION_task &&
15784         (CurrDir == OMPD_taskgroup ||
15785          ((isOpenMPParallelDirective(CurrDir) ||
15786            isOpenMPWorksharingDirective(CurrDir)) &&
15787           !isOpenMPSimdDirective(CurrDir)))) {
15788       if (DeclareReductionRef.isUsable())
15789         Stack->addTaskgroupReductionData(D, ReductionIdRange,
15790                                          DeclareReductionRef.get());
15791       else
15792         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15793     }
15794     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15795             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15796             TempArrayElem.get());
15797   }
15798   return RD.Vars.empty();
15799 }
15800 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15801 OMPClause *Sema::ActOnOpenMPReductionClause(
15802     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15803     SourceLocation StartLoc, SourceLocation LParenLoc,
15804     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15805     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15806     ArrayRef<Expr *> UnresolvedReductions) {
15807   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15808     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15809         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15810                                    /*Last=*/OMPC_REDUCTION_unknown)
15811         << getOpenMPClauseName(OMPC_reduction);
15812     return nullptr;
15813   }
15814   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15815   // A reduction clause with the inscan reduction-modifier may only appear on a
15816   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15817   // construct, a parallel worksharing-loop construct or a parallel
15818   // worksharing-loop SIMD construct.
15819   if (Modifier == OMPC_REDUCTION_inscan &&
15820       (DSAStack->getCurrentDirective() != OMPD_for &&
15821        DSAStack->getCurrentDirective() != OMPD_for_simd &&
15822        DSAStack->getCurrentDirective() != OMPD_simd &&
15823        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
15824        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
15825     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15826     return nullptr;
15827   }
15828 
15829   ReductionData RD(VarList.size(), Modifier);
15830   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
15831                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
15832                                   ReductionIdScopeSpec, ReductionId,
15833                                   UnresolvedReductions, RD))
15834     return nullptr;
15835 
15836   return OMPReductionClause::Create(
15837       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15838       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15839       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15840       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15841       buildPreInits(Context, RD.ExprCaptures),
15842       buildPostUpdate(*this, RD.ExprPostUpdates));
15843 }
15844 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15845 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15846     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15847     SourceLocation ColonLoc, SourceLocation EndLoc,
15848     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15849     ArrayRef<Expr *> UnresolvedReductions) {
15850   ReductionData RD(VarList.size());
15851   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
15852                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
15853                                   ReductionIdScopeSpec, ReductionId,
15854                                   UnresolvedReductions, RD))
15855     return nullptr;
15856 
15857   return OMPTaskReductionClause::Create(
15858       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15859       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15860       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15861       buildPreInits(Context, RD.ExprCaptures),
15862       buildPostUpdate(*this, RD.ExprPostUpdates));
15863 }
15864 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15865 OMPClause *Sema::ActOnOpenMPInReductionClause(
15866     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15867     SourceLocation ColonLoc, SourceLocation EndLoc,
15868     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15869     ArrayRef<Expr *> UnresolvedReductions) {
15870   ReductionData RD(VarList.size());
15871   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
15872                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
15873                                   ReductionIdScopeSpec, ReductionId,
15874                                   UnresolvedReductions, RD))
15875     return nullptr;
15876 
15877   return OMPInReductionClause::Create(
15878       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15879       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15880       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15881       buildPreInits(Context, RD.ExprCaptures),
15882       buildPostUpdate(*this, RD.ExprPostUpdates));
15883 }
15884 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)15885 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15886                                      SourceLocation LinLoc) {
15887   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15888       LinKind == OMPC_LINEAR_unknown) {
15889     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15890     return true;
15891   }
15892   return false;
15893 }
15894 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)15895 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15896                                  OpenMPLinearClauseKind LinKind, QualType Type,
15897                                  bool IsDeclareSimd) {
15898   const auto *VD = dyn_cast_or_null<VarDecl>(D);
15899   // A variable must not have an incomplete type or a reference type.
15900   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15901     return true;
15902   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15903       !Type->isReferenceType()) {
15904     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15905         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15906     return true;
15907   }
15908   Type = Type.getNonReferenceType();
15909 
15910   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15911   // A variable that is privatized must not have a const-qualified type
15912   // unless it is of class type with a mutable member. This restriction does
15913   // not apply to the firstprivate clause, nor to the linear clause on
15914   // declarative directives (like declare simd).
15915   if (!IsDeclareSimd &&
15916       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15917     return true;
15918 
15919   // A list item must be of integral or pointer type.
15920   Type = Type.getUnqualifiedType().getCanonicalType();
15921   const auto *Ty = Type.getTypePtrOrNull();
15922   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15923               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15924     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15925     if (D) {
15926       bool IsDecl =
15927           !VD ||
15928           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15929       Diag(D->getLocation(),
15930            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15931           << D;
15932     }
15933     return true;
15934   }
15935   return false;
15936 }
15937 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)15938 OMPClause *Sema::ActOnOpenMPLinearClause(
15939     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15940     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15941     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15942   SmallVector<Expr *, 8> Vars;
15943   SmallVector<Expr *, 8> Privates;
15944   SmallVector<Expr *, 8> Inits;
15945   SmallVector<Decl *, 4> ExprCaptures;
15946   SmallVector<Expr *, 4> ExprPostUpdates;
15947   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15948     LinKind = OMPC_LINEAR_val;
15949   for (Expr *RefExpr : VarList) {
15950     assert(RefExpr && "NULL expr in OpenMP linear clause.");
15951     SourceLocation ELoc;
15952     SourceRange ERange;
15953     Expr *SimpleRefExpr = RefExpr;
15954     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15955     if (Res.second) {
15956       // It will be analyzed later.
15957       Vars.push_back(RefExpr);
15958       Privates.push_back(nullptr);
15959       Inits.push_back(nullptr);
15960     }
15961     ValueDecl *D = Res.first;
15962     if (!D)
15963       continue;
15964 
15965     QualType Type = D->getType();
15966     auto *VD = dyn_cast<VarDecl>(D);
15967 
15968     // OpenMP [2.14.3.7, linear clause]
15969     //  A list-item cannot appear in more than one linear clause.
15970     //  A list-item that appears in a linear clause cannot appear in any
15971     //  other data-sharing attribute clause.
15972     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15973     if (DVar.RefExpr) {
15974       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15975                                           << getOpenMPClauseName(OMPC_linear);
15976       reportOriginalDsa(*this, DSAStack, D, DVar);
15977       continue;
15978     }
15979 
15980     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15981       continue;
15982     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15983 
15984     // Build private copy of original var.
15985     VarDecl *Private =
15986         buildVarDecl(*this, ELoc, Type, D->getName(),
15987                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15988                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15989     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15990     // Build var to save initial value.
15991     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15992     Expr *InitExpr;
15993     DeclRefExpr *Ref = nullptr;
15994     if (!VD && !CurContext->isDependentContext()) {
15995       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15996       if (!isOpenMPCapturedDecl(D)) {
15997         ExprCaptures.push_back(Ref->getDecl());
15998         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15999           ExprResult RefRes = DefaultLvalueConversion(Ref);
16000           if (!RefRes.isUsable())
16001             continue;
16002           ExprResult PostUpdateRes =
16003               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
16004                          SimpleRefExpr, RefRes.get());
16005           if (!PostUpdateRes.isUsable())
16006             continue;
16007           ExprPostUpdates.push_back(
16008               IgnoredValueConversions(PostUpdateRes.get()).get());
16009         }
16010       }
16011     }
16012     if (LinKind == OMPC_LINEAR_uval)
16013       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
16014     else
16015       InitExpr = VD ? SimpleRefExpr : Ref;
16016     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
16017                          /*DirectInit=*/false);
16018     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
16019 
16020     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
16021     Vars.push_back((VD || CurContext->isDependentContext())
16022                        ? RefExpr->IgnoreParens()
16023                        : Ref);
16024     Privates.push_back(PrivateRef);
16025     Inits.push_back(InitRef);
16026   }
16027 
16028   if (Vars.empty())
16029     return nullptr;
16030 
16031   Expr *StepExpr = Step;
16032   Expr *CalcStepExpr = nullptr;
16033   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
16034       !Step->isInstantiationDependent() &&
16035       !Step->containsUnexpandedParameterPack()) {
16036     SourceLocation StepLoc = Step->getBeginLoc();
16037     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
16038     if (Val.isInvalid())
16039       return nullptr;
16040     StepExpr = Val.get();
16041 
16042     // Build var to save the step value.
16043     VarDecl *SaveVar =
16044         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
16045     ExprResult SaveRef =
16046         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
16047     ExprResult CalcStep =
16048         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
16049     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
16050 
16051     // Warn about zero linear step (it would be probably better specified as
16052     // making corresponding variables 'const').
16053     if (Optional<llvm::APSInt> Result =
16054             StepExpr->getIntegerConstantExpr(Context)) {
16055       if (!Result->isNegative() && !Result->isStrictlyPositive())
16056         Diag(StepLoc, diag::warn_omp_linear_step_zero)
16057             << Vars[0] << (Vars.size() > 1);
16058     } else if (CalcStep.isUsable()) {
16059       // Calculate the step beforehand instead of doing this on each iteration.
16060       // (This is not used if the number of iterations may be kfold-ed).
16061       CalcStepExpr = CalcStep.get();
16062     }
16063   }
16064 
16065   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
16066                                  ColonLoc, EndLoc, Vars, Privates, Inits,
16067                                  StepExpr, CalcStepExpr,
16068                                  buildPreInits(Context, ExprCaptures),
16069                                  buildPostUpdate(*this, ExprPostUpdates));
16070 }
16071 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)16072 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
16073                                      Expr *NumIterations, Sema &SemaRef,
16074                                      Scope *S, DSAStackTy *Stack) {
16075   // Walk the vars and build update/final expressions for the CodeGen.
16076   SmallVector<Expr *, 8> Updates;
16077   SmallVector<Expr *, 8> Finals;
16078   SmallVector<Expr *, 8> UsedExprs;
16079   Expr *Step = Clause.getStep();
16080   Expr *CalcStep = Clause.getCalcStep();
16081   // OpenMP [2.14.3.7, linear clause]
16082   // If linear-step is not specified it is assumed to be 1.
16083   if (!Step)
16084     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
16085   else if (CalcStep)
16086     Step = cast<BinaryOperator>(CalcStep)->getLHS();
16087   bool HasErrors = false;
16088   auto CurInit = Clause.inits().begin();
16089   auto CurPrivate = Clause.privates().begin();
16090   OpenMPLinearClauseKind LinKind = Clause.getModifier();
16091   for (Expr *RefExpr : Clause.varlists()) {
16092     SourceLocation ELoc;
16093     SourceRange ERange;
16094     Expr *SimpleRefExpr = RefExpr;
16095     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
16096     ValueDecl *D = Res.first;
16097     if (Res.second || !D) {
16098       Updates.push_back(nullptr);
16099       Finals.push_back(nullptr);
16100       HasErrors = true;
16101       continue;
16102     }
16103     auto &&Info = Stack->isLoopControlVariable(D);
16104     // OpenMP [2.15.11, distribute simd Construct]
16105     // A list item may not appear in a linear clause, unless it is the loop
16106     // iteration variable.
16107     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
16108         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
16109       SemaRef.Diag(ELoc,
16110                    diag::err_omp_linear_distribute_var_non_loop_iteration);
16111       Updates.push_back(nullptr);
16112       Finals.push_back(nullptr);
16113       HasErrors = true;
16114       continue;
16115     }
16116     Expr *InitExpr = *CurInit;
16117 
16118     // Build privatized reference to the current linear var.
16119     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
16120     Expr *CapturedRef;
16121     if (LinKind == OMPC_LINEAR_uval)
16122       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
16123     else
16124       CapturedRef =
16125           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
16126                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
16127                            /*RefersToCapture=*/true);
16128 
16129     // Build update: Var = InitExpr + IV * Step
16130     ExprResult Update;
16131     if (!Info.first)
16132       Update = buildCounterUpdate(
16133           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
16134           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
16135     else
16136       Update = *CurPrivate;
16137     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
16138                                          /*DiscardedValue*/ false);
16139 
16140     // Build final: Var = InitExpr + NumIterations * Step
16141     ExprResult Final;
16142     if (!Info.first)
16143       Final =
16144           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
16145                              InitExpr, NumIterations, Step, /*Subtract=*/false,
16146                              /*IsNonRectangularLB=*/false);
16147     else
16148       Final = *CurPrivate;
16149     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
16150                                         /*DiscardedValue*/ false);
16151 
16152     if (!Update.isUsable() || !Final.isUsable()) {
16153       Updates.push_back(nullptr);
16154       Finals.push_back(nullptr);
16155       UsedExprs.push_back(nullptr);
16156       HasErrors = true;
16157     } else {
16158       Updates.push_back(Update.get());
16159       Finals.push_back(Final.get());
16160       if (!Info.first)
16161         UsedExprs.push_back(SimpleRefExpr);
16162     }
16163     ++CurInit;
16164     ++CurPrivate;
16165   }
16166   if (Expr *S = Clause.getStep())
16167     UsedExprs.push_back(S);
16168   // Fill the remaining part with the nullptr.
16169   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16170   Clause.setUpdates(Updates);
16171   Clause.setFinals(Finals);
16172   Clause.setUsedExprs(UsedExprs);
16173   return HasErrors;
16174 }
16175 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)16176 OMPClause *Sema::ActOnOpenMPAlignedClause(
16177     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16178     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16179   SmallVector<Expr *, 8> Vars;
16180   for (Expr *RefExpr : VarList) {
16181     assert(RefExpr && "NULL expr in OpenMP linear clause.");
16182     SourceLocation ELoc;
16183     SourceRange ERange;
16184     Expr *SimpleRefExpr = RefExpr;
16185     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16186     if (Res.second) {
16187       // It will be analyzed later.
16188       Vars.push_back(RefExpr);
16189     }
16190     ValueDecl *D = Res.first;
16191     if (!D)
16192       continue;
16193 
16194     QualType QType = D->getType();
16195     auto *VD = dyn_cast<VarDecl>(D);
16196 
16197     // OpenMP  [2.8.1, simd construct, Restrictions]
16198     // The type of list items appearing in the aligned clause must be
16199     // array, pointer, reference to array, or reference to pointer.
16200     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16201     const Type *Ty = QType.getTypePtrOrNull();
16202     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16203       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16204           << QType << getLangOpts().CPlusPlus << ERange;
16205       bool IsDecl =
16206           !VD ||
16207           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16208       Diag(D->getLocation(),
16209            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16210           << D;
16211       continue;
16212     }
16213 
16214     // OpenMP  [2.8.1, simd construct, Restrictions]
16215     // A list-item cannot appear in more than one aligned clause.
16216     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
16217       Diag(ELoc, diag::err_omp_used_in_clause_twice)
16218           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16219       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16220           << getOpenMPClauseName(OMPC_aligned);
16221       continue;
16222     }
16223 
16224     DeclRefExpr *Ref = nullptr;
16225     if (!VD && isOpenMPCapturedDecl(D))
16226       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16227     Vars.push_back(DefaultFunctionArrayConversion(
16228                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16229                        .get());
16230   }
16231 
16232   // OpenMP [2.8.1, simd construct, Description]
16233   // The parameter of the aligned clause, alignment, must be a constant
16234   // positive integer expression.
16235   // If no optional parameter is specified, implementation-defined default
16236   // alignments for SIMD instructions on the target platforms are assumed.
16237   if (Alignment != nullptr) {
16238     ExprResult AlignResult =
16239         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16240     if (AlignResult.isInvalid())
16241       return nullptr;
16242     Alignment = AlignResult.get();
16243   }
16244   if (Vars.empty())
16245     return nullptr;
16246 
16247   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16248                                   EndLoc, Vars, Alignment);
16249 }
16250 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16251 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16252                                          SourceLocation StartLoc,
16253                                          SourceLocation LParenLoc,
16254                                          SourceLocation EndLoc) {
16255   SmallVector<Expr *, 8> Vars;
16256   SmallVector<Expr *, 8> SrcExprs;
16257   SmallVector<Expr *, 8> DstExprs;
16258   SmallVector<Expr *, 8> AssignmentOps;
16259   for (Expr *RefExpr : VarList) {
16260     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
16261     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16262       // It will be analyzed later.
16263       Vars.push_back(RefExpr);
16264       SrcExprs.push_back(nullptr);
16265       DstExprs.push_back(nullptr);
16266       AssignmentOps.push_back(nullptr);
16267       continue;
16268     }
16269 
16270     SourceLocation ELoc = RefExpr->getExprLoc();
16271     // OpenMP [2.1, C/C++]
16272     //  A list item is a variable name.
16273     // OpenMP  [2.14.4.1, Restrictions, p.1]
16274     //  A list item that appears in a copyin clause must be threadprivate.
16275     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16276     if (!DE || !isa<VarDecl>(DE->getDecl())) {
16277       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16278           << 0 << RefExpr->getSourceRange();
16279       continue;
16280     }
16281 
16282     Decl *D = DE->getDecl();
16283     auto *VD = cast<VarDecl>(D);
16284 
16285     QualType Type = VD->getType();
16286     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16287       // It will be analyzed later.
16288       Vars.push_back(DE);
16289       SrcExprs.push_back(nullptr);
16290       DstExprs.push_back(nullptr);
16291       AssignmentOps.push_back(nullptr);
16292       continue;
16293     }
16294 
16295     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16296     //  A list item that appears in a copyin clause must be threadprivate.
16297     if (!DSAStack->isThreadPrivate(VD)) {
16298       Diag(ELoc, diag::err_omp_required_access)
16299           << getOpenMPClauseName(OMPC_copyin)
16300           << getOpenMPDirectiveName(OMPD_threadprivate);
16301       continue;
16302     }
16303 
16304     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16305     //  A variable of class type (or array thereof) that appears in a
16306     //  copyin clause requires an accessible, unambiguous copy assignment
16307     //  operator for the class type.
16308     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16309     VarDecl *SrcVD =
16310         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16311                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16312     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16313         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16314     VarDecl *DstVD =
16315         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16316                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16317     DeclRefExpr *PseudoDstExpr =
16318         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16319     // For arrays generate assignment operation for single element and replace
16320     // it by the original array element in CodeGen.
16321     ExprResult AssignmentOp =
16322         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16323                    PseudoSrcExpr);
16324     if (AssignmentOp.isInvalid())
16325       continue;
16326     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16327                                        /*DiscardedValue*/ false);
16328     if (AssignmentOp.isInvalid())
16329       continue;
16330 
16331     DSAStack->addDSA(VD, DE, OMPC_copyin);
16332     Vars.push_back(DE);
16333     SrcExprs.push_back(PseudoSrcExpr);
16334     DstExprs.push_back(PseudoDstExpr);
16335     AssignmentOps.push_back(AssignmentOp.get());
16336   }
16337 
16338   if (Vars.empty())
16339     return nullptr;
16340 
16341   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16342                                  SrcExprs, DstExprs, AssignmentOps);
16343 }
16344 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16345 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16346                                               SourceLocation StartLoc,
16347                                               SourceLocation LParenLoc,
16348                                               SourceLocation EndLoc) {
16349   SmallVector<Expr *, 8> Vars;
16350   SmallVector<Expr *, 8> SrcExprs;
16351   SmallVector<Expr *, 8> DstExprs;
16352   SmallVector<Expr *, 8> AssignmentOps;
16353   for (Expr *RefExpr : VarList) {
16354     assert(RefExpr && "NULL expr in OpenMP linear clause.");
16355     SourceLocation ELoc;
16356     SourceRange ERange;
16357     Expr *SimpleRefExpr = RefExpr;
16358     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16359     if (Res.second) {
16360       // It will be analyzed later.
16361       Vars.push_back(RefExpr);
16362       SrcExprs.push_back(nullptr);
16363       DstExprs.push_back(nullptr);
16364       AssignmentOps.push_back(nullptr);
16365     }
16366     ValueDecl *D = Res.first;
16367     if (!D)
16368       continue;
16369 
16370     QualType Type = D->getType();
16371     auto *VD = dyn_cast<VarDecl>(D);
16372 
16373     // OpenMP [2.14.4.2, Restrictions, p.2]
16374     //  A list item that appears in a copyprivate clause may not appear in a
16375     //  private or firstprivate clause on the single construct.
16376     if (!VD || !DSAStack->isThreadPrivate(VD)) {
16377       DSAStackTy::DSAVarData DVar =
16378           DSAStack->getTopDSA(D, /*FromParent=*/false);
16379       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16380           DVar.RefExpr) {
16381         Diag(ELoc, diag::err_omp_wrong_dsa)
16382             << getOpenMPClauseName(DVar.CKind)
16383             << getOpenMPClauseName(OMPC_copyprivate);
16384         reportOriginalDsa(*this, DSAStack, D, DVar);
16385         continue;
16386       }
16387 
16388       // OpenMP [2.11.4.2, Restrictions, p.1]
16389       //  All list items that appear in a copyprivate clause must be either
16390       //  threadprivate or private in the enclosing context.
16391       if (DVar.CKind == OMPC_unknown) {
16392         DVar = DSAStack->getImplicitDSA(D, false);
16393         if (DVar.CKind == OMPC_shared) {
16394           Diag(ELoc, diag::err_omp_required_access)
16395               << getOpenMPClauseName(OMPC_copyprivate)
16396               << "threadprivate or private in the enclosing context";
16397           reportOriginalDsa(*this, DSAStack, D, DVar);
16398           continue;
16399         }
16400       }
16401     }
16402 
16403     // Variably modified types are not supported.
16404     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16405       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16406           << getOpenMPClauseName(OMPC_copyprivate) << Type
16407           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16408       bool IsDecl =
16409           !VD ||
16410           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16411       Diag(D->getLocation(),
16412            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16413           << D;
16414       continue;
16415     }
16416 
16417     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16418     //  A variable of class type (or array thereof) that appears in a
16419     //  copyin clause requires an accessible, unambiguous copy assignment
16420     //  operator for the class type.
16421     Type = Context.getBaseElementType(Type.getNonReferenceType())
16422                .getUnqualifiedType();
16423     VarDecl *SrcVD =
16424         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16425                      D->hasAttrs() ? &D->getAttrs() : nullptr);
16426     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16427     VarDecl *DstVD =
16428         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16429                      D->hasAttrs() ? &D->getAttrs() : nullptr);
16430     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16431     ExprResult AssignmentOp = BuildBinOp(
16432         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16433     if (AssignmentOp.isInvalid())
16434       continue;
16435     AssignmentOp =
16436         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16437     if (AssignmentOp.isInvalid())
16438       continue;
16439 
16440     // No need to mark vars as copyprivate, they are already threadprivate or
16441     // implicitly private.
16442     assert(VD || isOpenMPCapturedDecl(D));
16443     Vars.push_back(
16444         VD ? RefExpr->IgnoreParens()
16445            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16446     SrcExprs.push_back(PseudoSrcExpr);
16447     DstExprs.push_back(PseudoDstExpr);
16448     AssignmentOps.push_back(AssignmentOp.get());
16449   }
16450 
16451   if (Vars.empty())
16452     return nullptr;
16453 
16454   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16455                                       Vars, SrcExprs, DstExprs, AssignmentOps);
16456 }
16457 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16458 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16459                                         SourceLocation StartLoc,
16460                                         SourceLocation LParenLoc,
16461                                         SourceLocation EndLoc) {
16462   if (VarList.empty())
16463     return nullptr;
16464 
16465   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16466 }
16467 
16468 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)16469 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16470                            bool Diagnose = true) {
16471   QualType OMPDependT = Stack->getOMPDependT();
16472   if (!OMPDependT.isNull())
16473     return true;
16474   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16475   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16476   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16477     if (Diagnose)
16478       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16479     return false;
16480   }
16481   Stack->setOMPDependT(PT.get());
16482   return true;
16483 }
16484 
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16485 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16486                                          SourceLocation LParenLoc,
16487                                          SourceLocation EndLoc) {
16488   if (!Depobj)
16489     return nullptr;
16490 
16491   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
16492 
16493   // OpenMP 5.0, 2.17.10.1 depobj Construct
16494   // depobj is an lvalue expression of type omp_depend_t.
16495   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16496       !Depobj->isInstantiationDependent() &&
16497       !Depobj->containsUnexpandedParameterPack() &&
16498       (OMPDependTFound &&
16499        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
16500                                    /*CompareUnqualified=*/true))) {
16501     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16502         << 0 << Depobj->getType() << Depobj->getSourceRange();
16503   }
16504 
16505   if (!Depobj->isLValue()) {
16506     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16507         << 1 << Depobj->getSourceRange();
16508   }
16509 
16510   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16511 }
16512 
16513 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16514 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16515                               SourceLocation DepLoc, SourceLocation ColonLoc,
16516                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16517                               SourceLocation LParenLoc, SourceLocation EndLoc) {
16518   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
16519       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16520     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16521         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16522     return nullptr;
16523   }
16524   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
16525        DSAStack->getCurrentDirective() == OMPD_depobj) &&
16526       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16527        DepKind == OMPC_DEPEND_sink ||
16528        ((LangOpts.OpenMP < 50 ||
16529          DSAStack->getCurrentDirective() == OMPD_depobj) &&
16530         DepKind == OMPC_DEPEND_depobj))) {
16531     SmallVector<unsigned, 3> Except;
16532     Except.push_back(OMPC_DEPEND_source);
16533     Except.push_back(OMPC_DEPEND_sink);
16534     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
16535       Except.push_back(OMPC_DEPEND_depobj);
16536     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16537                                ? "depend modifier(iterator) or "
16538                                : "";
16539     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16540         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16541                                               /*Last=*/OMPC_DEPEND_unknown,
16542                                               Except)
16543         << getOpenMPClauseName(OMPC_depend);
16544     return nullptr;
16545   }
16546   if (DepModifier &&
16547       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16548     Diag(DepModifier->getExprLoc(),
16549          diag::err_omp_depend_sink_source_with_modifier);
16550     return nullptr;
16551   }
16552   if (DepModifier &&
16553       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16554     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16555 
16556   SmallVector<Expr *, 8> Vars;
16557   DSAStackTy::OperatorOffsetTy OpsOffs;
16558   llvm::APSInt DepCounter(/*BitWidth=*/32);
16559   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16560   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16561     if (const Expr *OrderedCountExpr =
16562             DSAStack->getParentOrderedRegionParam().first) {
16563       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16564       TotalDepCount.setIsUnsigned(/*Val=*/true);
16565     }
16566   }
16567   for (Expr *RefExpr : VarList) {
16568     assert(RefExpr && "NULL expr in OpenMP shared clause.");
16569     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16570       // It will be analyzed later.
16571       Vars.push_back(RefExpr);
16572       continue;
16573     }
16574 
16575     SourceLocation ELoc = RefExpr->getExprLoc();
16576     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16577     if (DepKind == OMPC_DEPEND_sink) {
16578       if (DSAStack->getParentOrderedRegionParam().first &&
16579           DepCounter >= TotalDepCount) {
16580         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16581         continue;
16582       }
16583       ++DepCounter;
16584       // OpenMP  [2.13.9, Summary]
16585       // depend(dependence-type : vec), where dependence-type is:
16586       // 'sink' and where vec is the iteration vector, which has the form:
16587       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16588       // where n is the value specified by the ordered clause in the loop
16589       // directive, xi denotes the loop iteration variable of the i-th nested
16590       // loop associated with the loop directive, and di is a constant
16591       // non-negative integer.
16592       if (CurContext->isDependentContext()) {
16593         // It will be analyzed later.
16594         Vars.push_back(RefExpr);
16595         continue;
16596       }
16597       SimpleExpr = SimpleExpr->IgnoreImplicit();
16598       OverloadedOperatorKind OOK = OO_None;
16599       SourceLocation OOLoc;
16600       Expr *LHS = SimpleExpr;
16601       Expr *RHS = nullptr;
16602       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16603         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16604         OOLoc = BO->getOperatorLoc();
16605         LHS = BO->getLHS()->IgnoreParenImpCasts();
16606         RHS = BO->getRHS()->IgnoreParenImpCasts();
16607       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16608         OOK = OCE->getOperator();
16609         OOLoc = OCE->getOperatorLoc();
16610         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16611         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16612       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16613         OOK = MCE->getMethodDecl()
16614                   ->getNameInfo()
16615                   .getName()
16616                   .getCXXOverloadedOperator();
16617         OOLoc = MCE->getCallee()->getExprLoc();
16618         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16619         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16620       }
16621       SourceLocation ELoc;
16622       SourceRange ERange;
16623       auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16624       if (Res.second) {
16625         // It will be analyzed later.
16626         Vars.push_back(RefExpr);
16627       }
16628       ValueDecl *D = Res.first;
16629       if (!D)
16630         continue;
16631 
16632       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16633         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16634         continue;
16635       }
16636       if (RHS) {
16637         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16638             RHS, OMPC_depend, /*StrictlyPositive=*/false);
16639         if (RHSRes.isInvalid())
16640           continue;
16641       }
16642       if (!CurContext->isDependentContext() &&
16643           DSAStack->getParentOrderedRegionParam().first &&
16644           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
16645         const ValueDecl *VD =
16646             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
16647         if (VD)
16648           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16649               << 1 << VD;
16650         else
16651           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16652         continue;
16653       }
16654       OpsOffs.emplace_back(RHS, OOK);
16655     } else {
16656       bool OMPDependTFound = LangOpts.OpenMP >= 50;
16657       if (OMPDependTFound)
16658         OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
16659                                          DepKind == OMPC_DEPEND_depobj);
16660       if (DepKind == OMPC_DEPEND_depobj) {
16661         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16662         // List items used in depend clauses with the depobj dependence type
16663         // must be expressions of the omp_depend_t type.
16664         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16665             !RefExpr->isInstantiationDependent() &&
16666             !RefExpr->containsUnexpandedParameterPack() &&
16667             (OMPDependTFound &&
16668              !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
16669                                              RefExpr->getType()))) {
16670           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16671               << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16672           continue;
16673         }
16674         if (!RefExpr->isLValue()) {
16675           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16676               << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16677           continue;
16678         }
16679       } else {
16680         // OpenMP 5.0 [2.17.11, Restrictions]
16681         // List items used in depend clauses cannot be zero-length array
16682         // sections.
16683         QualType ExprTy = RefExpr->getType().getNonReferenceType();
16684         const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16685         if (OASE) {
16686           QualType BaseType =
16687               OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16688           if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16689             ExprTy = ATy->getElementType();
16690           else
16691             ExprTy = BaseType->getPointeeType();
16692           ExprTy = ExprTy.getNonReferenceType();
16693           const Expr *Length = OASE->getLength();
16694           Expr::EvalResult Result;
16695           if (Length && !Length->isValueDependent() &&
16696               Length->EvaluateAsInt(Result, Context) &&
16697               Result.Val.getInt().isNullValue()) {
16698             Diag(ELoc,
16699                  diag::err_omp_depend_zero_length_array_section_not_allowed)
16700                 << SimpleExpr->getSourceRange();
16701             continue;
16702           }
16703         }
16704 
16705         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16706         // List items used in depend clauses with the in, out, inout or
16707         // mutexinoutset dependence types cannot be expressions of the
16708         // omp_depend_t type.
16709         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16710             !RefExpr->isInstantiationDependent() &&
16711             !RefExpr->containsUnexpandedParameterPack() &&
16712             (OMPDependTFound &&
16713              DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16714           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16715               << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16716               << RefExpr->getSourceRange();
16717           continue;
16718         }
16719 
16720         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16721         if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16722             (ASE && !ASE->getBase()->isTypeDependent() &&
16723              !ASE->getBase()
16724                   ->getType()
16725                   .getNonReferenceType()
16726                   ->isPointerType() &&
16727              !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16728           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16729               << (LangOpts.OpenMP >= 50 ? 1 : 0)
16730               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16731           continue;
16732         }
16733 
16734         ExprResult Res;
16735         {
16736           Sema::TentativeAnalysisScope Trap(*this);
16737           Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16738                                      RefExpr->IgnoreParenImpCasts());
16739         }
16740         if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16741             !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16742           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16743               << (LangOpts.OpenMP >= 50 ? 1 : 0)
16744               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16745           continue;
16746         }
16747       }
16748     }
16749     Vars.push_back(RefExpr->IgnoreParenImpCasts());
16750   }
16751 
16752   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16753       TotalDepCount > VarList.size() &&
16754       DSAStack->getParentOrderedRegionParam().first &&
16755       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
16756     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16757         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
16758   }
16759   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16760       Vars.empty())
16761     return nullptr;
16762 
16763   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16764                                     DepModifier, DepKind, DepLoc, ColonLoc,
16765                                     Vars, TotalDepCount.getZExtValue());
16766   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16767       DSAStack->isParentOrderedRegion())
16768     DSAStack->addDoacrossDependClause(C, OpsOffs);
16769   return C;
16770 }
16771 
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)16772 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16773                                          Expr *Device, SourceLocation StartLoc,
16774                                          SourceLocation LParenLoc,
16775                                          SourceLocation ModifierLoc,
16776                                          SourceLocation EndLoc) {
16777   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
16778          "Unexpected device modifier in OpenMP < 50.");
16779 
16780   bool ErrorFound = false;
16781   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16782     std::string Values =
16783         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16784     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16785         << Values << getOpenMPClauseName(OMPC_device);
16786     ErrorFound = true;
16787   }
16788 
16789   Expr *ValExpr = Device;
16790   Stmt *HelperValStmt = nullptr;
16791 
16792   // OpenMP [2.9.1, Restrictions]
16793   // The device expression must evaluate to a non-negative integer value.
16794   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16795                                           /*StrictlyPositive=*/false) ||
16796                ErrorFound;
16797   if (ErrorFound)
16798     return nullptr;
16799 
16800   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16801   OpenMPDirectiveKind CaptureRegion =
16802       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16803   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16804     ValExpr = MakeFullExpr(ValExpr).get();
16805     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16806     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16807     HelperValStmt = buildPreInits(Context, Captures);
16808   }
16809 
16810   return new (Context)
16811       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16812                       LParenLoc, ModifierLoc, EndLoc);
16813 }
16814 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)16815 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16816                               DSAStackTy *Stack, QualType QTy,
16817                               bool FullCheck = true) {
16818   NamedDecl *ND;
16819   if (QTy->isIncompleteType(&ND)) {
16820     SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16821     return false;
16822   }
16823   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16824       !QTy.isTriviallyCopyableType(SemaRef.Context))
16825     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16826   return true;
16827 }
16828 
16829 /// Return true if it can be proven that the provided array expression
16830 /// (array section or array subscript) does NOT specify the whole size of the
16831 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)16832 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16833                                                         const Expr *E,
16834                                                         QualType BaseQTy) {
16835   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16836 
16837   // If this is an array subscript, it refers to the whole size if the size of
16838   // the dimension is constant and equals 1. Also, an array section assumes the
16839   // format of an array subscript if no colon is used.
16840   if (isa<ArraySubscriptExpr>(E) ||
16841       (OASE && OASE->getColonLocFirst().isInvalid())) {
16842     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16843       return ATy->getSize().getSExtValue() != 1;
16844     // Size can't be evaluated statically.
16845     return false;
16846   }
16847 
16848   assert(OASE && "Expecting array section if not an array subscript.");
16849   const Expr *LowerBound = OASE->getLowerBound();
16850   const Expr *Length = OASE->getLength();
16851 
16852   // If there is a lower bound that does not evaluates to zero, we are not
16853   // covering the whole dimension.
16854   if (LowerBound) {
16855     Expr::EvalResult Result;
16856     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16857       return false; // Can't get the integer value as a constant.
16858 
16859     llvm::APSInt ConstLowerBound = Result.Val.getInt();
16860     if (ConstLowerBound.getSExtValue())
16861       return true;
16862   }
16863 
16864   // If we don't have a length we covering the whole dimension.
16865   if (!Length)
16866     return false;
16867 
16868   // If the base is a pointer, we don't have a way to get the size of the
16869   // pointee.
16870   if (BaseQTy->isPointerType())
16871     return false;
16872 
16873   // We can only check if the length is the same as the size of the dimension
16874   // if we have a constant array.
16875   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16876   if (!CATy)
16877     return false;
16878 
16879   Expr::EvalResult Result;
16880   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16881     return false; // Can't get the integer value as a constant.
16882 
16883   llvm::APSInt ConstLength = Result.Val.getInt();
16884   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16885 }
16886 
16887 // Return true if it can be proven that the provided array expression (array
16888 // section or array subscript) does NOT specify a single element of the array
16889 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)16890 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16891                                                         const Expr *E,
16892                                                         QualType BaseQTy) {
16893   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16894 
16895   // An array subscript always refer to a single element. Also, an array section
16896   // assumes the format of an array subscript if no colon is used.
16897   if (isa<ArraySubscriptExpr>(E) ||
16898       (OASE && OASE->getColonLocFirst().isInvalid()))
16899     return false;
16900 
16901   assert(OASE && "Expecting array section if not an array subscript.");
16902   const Expr *Length = OASE->getLength();
16903 
16904   // If we don't have a length we have to check if the array has unitary size
16905   // for this dimension. Also, we should always expect a length if the base type
16906   // is pointer.
16907   if (!Length) {
16908     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16909       return ATy->getSize().getSExtValue() != 1;
16910     // We cannot assume anything.
16911     return false;
16912   }
16913 
16914   // Check if the length evaluates to 1.
16915   Expr::EvalResult Result;
16916   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16917     return false; // Can't get the integer value as a constant.
16918 
16919   llvm::APSInt ConstLength = Result.Val.getInt();
16920   return ConstLength.getSExtValue() != 1;
16921 }
16922 
16923 // The base of elements of list in a map clause have to be either:
16924 //  - a reference to variable or field.
16925 //  - a member expression.
16926 //  - an array expression.
16927 //
16928 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16929 // reference to 'r'.
16930 //
16931 // If we have:
16932 //
16933 // struct SS {
16934 //   Bla S;
16935 //   foo() {
16936 //     #pragma omp target map (S.Arr[:12]);
16937 //   }
16938 // }
16939 //
16940 // We want to retrieve the member expression 'this->S';
16941 
16942 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16943 //  If a list item is an array section, it must specify contiguous storage.
16944 //
16945 // For this restriction it is sufficient that we make sure only references
16946 // to variables or fields and array expressions, and that no array sections
16947 // exist except in the rightmost expression (unless they cover the whole
16948 // dimension of the array). E.g. these would be invalid:
16949 //
16950 //   r.ArrS[3:5].Arr[6:7]
16951 //
16952 //   r.ArrS[3:5].x
16953 //
16954 // but these would be valid:
16955 //   r.ArrS[3].Arr[6:7]
16956 //
16957 //   r.ArrS[3].x
16958 namespace {
16959 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16960   Sema &SemaRef;
16961   OpenMPClauseKind CKind = OMPC_unknown;
16962   OpenMPDirectiveKind DKind = OMPD_unknown;
16963   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16964   bool IsNonContiguous = false;
16965   bool NoDiagnose = false;
16966   const Expr *RelevantExpr = nullptr;
16967   bool AllowUnitySizeArraySection = true;
16968   bool AllowWholeSizeArraySection = true;
16969   bool AllowAnotherPtr = true;
16970   SourceLocation ELoc;
16971   SourceRange ERange;
16972 
emitErrorMsg()16973   void emitErrorMsg() {
16974     // If nothing else worked, this is not a valid map clause expression.
16975     if (SemaRef.getLangOpts().OpenMP < 50) {
16976       SemaRef.Diag(ELoc,
16977                    diag::err_omp_expected_named_var_member_or_array_expression)
16978           << ERange;
16979     } else {
16980       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16981           << getOpenMPClauseName(CKind) << ERange;
16982     }
16983   }
16984 
16985 public:
VisitDeclRefExpr(DeclRefExpr * DRE)16986   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16987     if (!isa<VarDecl>(DRE->getDecl())) {
16988       emitErrorMsg();
16989       return false;
16990     }
16991     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16992     RelevantExpr = DRE;
16993     // Record the component.
16994     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
16995     return true;
16996   }
16997 
VisitMemberExpr(MemberExpr * ME)16998   bool VisitMemberExpr(MemberExpr *ME) {
16999     Expr *E = ME;
17000     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
17001 
17002     if (isa<CXXThisExpr>(BaseE)) {
17003       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17004       // We found a base expression: this->Val.
17005       RelevantExpr = ME;
17006     } else {
17007       E = BaseE;
17008     }
17009 
17010     if (!isa<FieldDecl>(ME->getMemberDecl())) {
17011       if (!NoDiagnose) {
17012         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
17013           << ME->getSourceRange();
17014         return false;
17015       }
17016       if (RelevantExpr)
17017         return false;
17018       return Visit(E);
17019     }
17020 
17021     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
17022 
17023     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
17024     //  A bit-field cannot appear in a map clause.
17025     //
17026     if (FD->isBitField()) {
17027       if (!NoDiagnose) {
17028         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
17029           << ME->getSourceRange() << getOpenMPClauseName(CKind);
17030         return false;
17031       }
17032       if (RelevantExpr)
17033         return false;
17034       return Visit(E);
17035     }
17036 
17037     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17038     //  If the type of a list item is a reference to a type T then the type
17039     //  will be considered to be T for all purposes of this clause.
17040     QualType CurType = BaseE->getType().getNonReferenceType();
17041 
17042     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
17043     //  A list item cannot be a variable that is a member of a structure with
17044     //  a union type.
17045     //
17046     if (CurType->isUnionType()) {
17047       if (!NoDiagnose) {
17048         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
17049           << ME->getSourceRange();
17050         return false;
17051       }
17052       return RelevantExpr || Visit(E);
17053     }
17054 
17055     // If we got a member expression, we should not expect any array section
17056     // before that:
17057     //
17058     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
17059     //  If a list item is an element of a structure, only the rightmost symbol
17060     //  of the variable reference can be an array section.
17061     //
17062     AllowUnitySizeArraySection = false;
17063     AllowWholeSizeArraySection = false;
17064 
17065     // Record the component.
17066     Components.emplace_back(ME, FD, IsNonContiguous);
17067     return RelevantExpr || Visit(E);
17068   }
17069 
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)17070   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
17071     Expr *E = AE->getBase()->IgnoreParenImpCasts();
17072 
17073     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
17074       if (!NoDiagnose) {
17075         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17076           << 0 << AE->getSourceRange();
17077         return false;
17078       }
17079       return RelevantExpr || Visit(E);
17080     }
17081 
17082     // If we got an array subscript that express the whole dimension we
17083     // can have any array expressions before. If it only expressing part of
17084     // the dimension, we can only have unitary-size array expressions.
17085     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
17086                                                     E->getType()))
17087       AllowWholeSizeArraySection = false;
17088 
17089     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
17090       Expr::EvalResult Result;
17091       if (!AE->getIdx()->isValueDependent() &&
17092           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
17093           !Result.Val.getInt().isNullValue()) {
17094         SemaRef.Diag(AE->getIdx()->getExprLoc(),
17095                      diag::err_omp_invalid_map_this_expr);
17096         SemaRef.Diag(AE->getIdx()->getExprLoc(),
17097                      diag::note_omp_invalid_subscript_on_this_ptr_map);
17098       }
17099       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17100       RelevantExpr = TE;
17101     }
17102 
17103     // Record the component - we don't have any declaration associated.
17104     Components.emplace_back(AE, nullptr, IsNonContiguous);
17105 
17106     return RelevantExpr || Visit(E);
17107   }
17108 
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)17109   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
17110     assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
17111     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17112     QualType CurType =
17113       OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17114 
17115     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17116     //  If the type of a list item is a reference to a type T then the type
17117     //  will be considered to be T for all purposes of this clause.
17118     if (CurType->isReferenceType())
17119       CurType = CurType->getPointeeType();
17120 
17121     bool IsPointer = CurType->isAnyPointerType();
17122 
17123     if (!IsPointer && !CurType->isArrayType()) {
17124       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
17125         << 0 << OASE->getSourceRange();
17126       return false;
17127     }
17128 
17129     bool NotWhole =
17130       checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
17131     bool NotUnity =
17132       checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
17133 
17134     if (AllowWholeSizeArraySection) {
17135       // Any array section is currently allowed. Allowing a whole size array
17136       // section implies allowing a unity array section as well.
17137       //
17138       // If this array section refers to the whole dimension we can still
17139       // accept other array sections before this one, except if the base is a
17140       // pointer. Otherwise, only unitary sections are accepted.
17141       if (NotWhole || IsPointer)
17142         AllowWholeSizeArraySection = false;
17143     } else if (DKind == OMPD_target_update &&
17144                SemaRef.getLangOpts().OpenMP >= 50) {
17145       if (IsPointer && !AllowAnotherPtr)
17146         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
17147             << /*array of unknown bound */ 1;
17148       else
17149         IsNonContiguous = true;
17150     } else if (AllowUnitySizeArraySection && NotUnity) {
17151       // A unity or whole array section is not allowed and that is not
17152       // compatible with the properties of the current array section.
17153       SemaRef.Diag(
17154         ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
17155         << OASE->getSourceRange();
17156       return false;
17157     }
17158 
17159     if (IsPointer)
17160       AllowAnotherPtr = false;
17161 
17162     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
17163       Expr::EvalResult ResultR;
17164       Expr::EvalResult ResultL;
17165       if (!OASE->getLength()->isValueDependent() &&
17166           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
17167           !ResultR.Val.getInt().isOneValue()) {
17168         SemaRef.Diag(OASE->getLength()->getExprLoc(),
17169                      diag::err_omp_invalid_map_this_expr);
17170         SemaRef.Diag(OASE->getLength()->getExprLoc(),
17171                      diag::note_omp_invalid_length_on_this_ptr_mapping);
17172       }
17173       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
17174           OASE->getLowerBound()->EvaluateAsInt(ResultL,
17175                                                SemaRef.getASTContext()) &&
17176           !ResultL.Val.getInt().isNullValue()) {
17177         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17178                      diag::err_omp_invalid_map_this_expr);
17179         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17180                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17181       }
17182       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17183       RelevantExpr = TE;
17184     }
17185 
17186     // Record the component - we don't have any declaration associated.
17187     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
17188     return RelevantExpr || Visit(E);
17189   }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)17190   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17191     Expr *Base = E->getBase();
17192 
17193     // Record the component - we don't have any declaration associated.
17194     Components.emplace_back(E, nullptr, IsNonContiguous);
17195 
17196     return Visit(Base->IgnoreParenImpCasts());
17197   }
17198 
VisitUnaryOperator(UnaryOperator * UO)17199   bool VisitUnaryOperator(UnaryOperator *UO) {
17200     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17201         UO->getOpcode() != UO_Deref) {
17202       emitErrorMsg();
17203       return false;
17204     }
17205     if (!RelevantExpr) {
17206       // Record the component if haven't found base decl.
17207       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
17208     }
17209     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17210   }
VisitBinaryOperator(BinaryOperator * BO)17211   bool VisitBinaryOperator(BinaryOperator *BO) {
17212     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17213       emitErrorMsg();
17214       return false;
17215     }
17216 
17217     // Pointer arithmetic is the only thing we expect to happen here so after we
17218     // make sure the binary operator is a pointer type, the we only thing need
17219     // to to is to visit the subtree that has the same type as root (so that we
17220     // know the other subtree is just an offset)
17221     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17222     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17223     Components.emplace_back(BO, nullptr, false);
17224     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
17225             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
17226            "Either LHS or RHS have base decl inside");
17227     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17228       return RelevantExpr || Visit(LE);
17229     return RelevantExpr || Visit(RE);
17230   }
VisitCXXThisExpr(CXXThisExpr * CTE)17231   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17232     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17233     RelevantExpr = CTE;
17234     Components.emplace_back(CTE, nullptr, IsNonContiguous);
17235     return true;
17236   }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)17237   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17238     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17239     Components.emplace_back(COCE, nullptr, IsNonContiguous);
17240     return true;
17241   }
VisitStmt(Stmt *)17242   bool VisitStmt(Stmt *) {
17243     emitErrorMsg();
17244     return false;
17245   }
getFoundBase() const17246   const Expr *getFoundBase() const {
17247     return RelevantExpr;
17248   }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)17249   explicit MapBaseChecker(
17250       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
17251       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17252       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17253       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
17254         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17255 };
17256 } // namespace
17257 
17258 /// Return the expression of the base of the mappable expression or null if it
17259 /// cannot be determined and do all the necessary checks to see if the expression
17260 /// is valid as a standalone mappable expression. In the process, record all the
17261 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)17262 static const Expr *checkMapClauseExpressionBase(
17263     Sema &SemaRef, Expr *E,
17264     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17265     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
17266   SourceLocation ELoc = E->getExprLoc();
17267   SourceRange ERange = E->getSourceRange();
17268   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
17269                          ERange);
17270   if (Checker.Visit(E->IgnoreParens())) {
17271     // Check if the highest dimension array section has length specified
17272     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
17273         (CKind == OMPC_to || CKind == OMPC_from)) {
17274       auto CI = CurComponents.rbegin();
17275       auto CE = CurComponents.rend();
17276       for (; CI != CE; ++CI) {
17277         const auto *OASE =
17278             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
17279         if (!OASE)
17280           continue;
17281         if (OASE && OASE->getLength())
17282           break;
17283         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
17284             << ERange;
17285       }
17286     }
17287     return Checker.getFoundBase();
17288   }
17289   return nullptr;
17290 }
17291 
17292 // Return true if expression E associated with value VD has conflicts with other
17293 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)17294 static bool checkMapConflicts(
17295     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17296     bool CurrentRegionOnly,
17297     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17298     OpenMPClauseKind CKind) {
17299   assert(VD && E);
17300   SourceLocation ELoc = E->getExprLoc();
17301   SourceRange ERange = E->getSourceRange();
17302 
17303   // In order to easily check the conflicts we need to match each component of
17304   // the expression under test with the components of the expressions that are
17305   // already in the stack.
17306 
17307   assert(!CurComponents.empty() && "Map clause expression with no components!");
17308   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
17309          "Map clause expression with unexpected base!");
17310 
17311   // Variables to help detecting enclosing problems in data environment nests.
17312   bool IsEnclosedByDataEnvironmentExpr = false;
17313   const Expr *EnclosingExpr = nullptr;
17314 
17315   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17316       VD, CurrentRegionOnly,
17317       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17318        ERange, CKind, &EnclosingExpr,
17319        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17320                           StackComponents,
17321                       OpenMPClauseKind) {
17322         assert(!StackComponents.empty() &&
17323                "Map clause expression with no components!");
17324         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
17325                "Map clause expression with unexpected base!");
17326         (void)VD;
17327 
17328         // The whole expression in the stack.
17329         const Expr *RE = StackComponents.front().getAssociatedExpression();
17330 
17331         // Expressions must start from the same base. Here we detect at which
17332         // point both expressions diverge from each other and see if we can
17333         // detect if the memory referred to both expressions is contiguous and
17334         // do not overlap.
17335         auto CI = CurComponents.rbegin();
17336         auto CE = CurComponents.rend();
17337         auto SI = StackComponents.rbegin();
17338         auto SE = StackComponents.rend();
17339         for (; CI != CE && SI != SE; ++CI, ++SI) {
17340 
17341           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17342           //  At most one list item can be an array item derived from a given
17343           //  variable in map clauses of the same construct.
17344           if (CurrentRegionOnly &&
17345               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17346                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17347                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17348               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17349                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17350                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17351             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17352                          diag::err_omp_multiple_array_items_in_map_clause)
17353                 << CI->getAssociatedExpression()->getSourceRange();
17354             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17355                          diag::note_used_here)
17356                 << SI->getAssociatedExpression()->getSourceRange();
17357             return true;
17358           }
17359 
17360           // Do both expressions have the same kind?
17361           if (CI->getAssociatedExpression()->getStmtClass() !=
17362               SI->getAssociatedExpression()->getStmtClass())
17363             break;
17364 
17365           // Are we dealing with different variables/fields?
17366           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17367             break;
17368         }
17369         // Check if the extra components of the expressions in the enclosing
17370         // data environment are redundant for the current base declaration.
17371         // If they are, the maps completely overlap, which is legal.
17372         for (; SI != SE; ++SI) {
17373           QualType Type;
17374           if (const auto *ASE =
17375                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17376             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17377           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17378                          SI->getAssociatedExpression())) {
17379             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17380             Type =
17381                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17382           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17383                          SI->getAssociatedExpression())) {
17384             Type = OASE->getBase()->getType()->getPointeeType();
17385           }
17386           if (Type.isNull() || Type->isAnyPointerType() ||
17387               checkArrayExpressionDoesNotReferToWholeSize(
17388                   SemaRef, SI->getAssociatedExpression(), Type))
17389             break;
17390         }
17391 
17392         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17393         //  List items of map clauses in the same construct must not share
17394         //  original storage.
17395         //
17396         // If the expressions are exactly the same or one is a subset of the
17397         // other, it means they are sharing storage.
17398         if (CI == CE && SI == SE) {
17399           if (CurrentRegionOnly) {
17400             if (CKind == OMPC_map) {
17401               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17402             } else {
17403               assert(CKind == OMPC_to || CKind == OMPC_from);
17404               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17405                   << ERange;
17406             }
17407             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17408                 << RE->getSourceRange();
17409             return true;
17410           }
17411           // If we find the same expression in the enclosing data environment,
17412           // that is legal.
17413           IsEnclosedByDataEnvironmentExpr = true;
17414           return false;
17415         }
17416 
17417         QualType DerivedType =
17418             std::prev(CI)->getAssociatedDeclaration()->getType();
17419         SourceLocation DerivedLoc =
17420             std::prev(CI)->getAssociatedExpression()->getExprLoc();
17421 
17422         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17423         //  If the type of a list item is a reference to a type T then the type
17424         //  will be considered to be T for all purposes of this clause.
17425         DerivedType = DerivedType.getNonReferenceType();
17426 
17427         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17428         //  A variable for which the type is pointer and an array section
17429         //  derived from that variable must not appear as list items of map
17430         //  clauses of the same construct.
17431         //
17432         // Also, cover one of the cases in:
17433         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17434         //  If any part of the original storage of a list item has corresponding
17435         //  storage in the device data environment, all of the original storage
17436         //  must have corresponding storage in the device data environment.
17437         //
17438         if (DerivedType->isAnyPointerType()) {
17439           if (CI == CE || SI == SE) {
17440             SemaRef.Diag(
17441                 DerivedLoc,
17442                 diag::err_omp_pointer_mapped_along_with_derived_section)
17443                 << DerivedLoc;
17444             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17445                 << RE->getSourceRange();
17446             return true;
17447           }
17448           if (CI->getAssociatedExpression()->getStmtClass() !=
17449                          SI->getAssociatedExpression()->getStmtClass() ||
17450                      CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17451                          SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17452             assert(CI != CE && SI != SE);
17453             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17454                 << DerivedLoc;
17455             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17456                 << RE->getSourceRange();
17457             return true;
17458           }
17459         }
17460 
17461         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17462         //  List items of map clauses in the same construct must not share
17463         //  original storage.
17464         //
17465         // An expression is a subset of the other.
17466         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17467           if (CKind == OMPC_map) {
17468             if (CI != CE || SI != SE) {
17469               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17470               // a pointer.
17471               auto Begin =
17472                   CI != CE ? CurComponents.begin() : StackComponents.begin();
17473               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17474               auto It = Begin;
17475               while (It != End && !It->getAssociatedDeclaration())
17476                 std::advance(It, 1);
17477               assert(It != End &&
17478                      "Expected at least one component with the declaration.");
17479               if (It != Begin && It->getAssociatedDeclaration()
17480                                      ->getType()
17481                                      .getCanonicalType()
17482                                      ->isAnyPointerType()) {
17483                 IsEnclosedByDataEnvironmentExpr = false;
17484                 EnclosingExpr = nullptr;
17485                 return false;
17486               }
17487             }
17488             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17489           } else {
17490             assert(CKind == OMPC_to || CKind == OMPC_from);
17491             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17492                 << ERange;
17493           }
17494           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17495               << RE->getSourceRange();
17496           return true;
17497         }
17498 
17499         // The current expression uses the same base as other expression in the
17500         // data environment but does not contain it completely.
17501         if (!CurrentRegionOnly && SI != SE)
17502           EnclosingExpr = RE;
17503 
17504         // The current expression is a subset of the expression in the data
17505         // environment.
17506         IsEnclosedByDataEnvironmentExpr |=
17507             (!CurrentRegionOnly && CI != CE && SI == SE);
17508 
17509         return false;
17510       });
17511 
17512   if (CurrentRegionOnly)
17513     return FoundError;
17514 
17515   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17516   //  If any part of the original storage of a list item has corresponding
17517   //  storage in the device data environment, all of the original storage must
17518   //  have corresponding storage in the device data environment.
17519   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17520   //  If a list item is an element of a structure, and a different element of
17521   //  the structure has a corresponding list item in the device data environment
17522   //  prior to a task encountering the construct associated with the map clause,
17523   //  then the list item must also have a corresponding list item in the device
17524   //  data environment prior to the task encountering the construct.
17525   //
17526   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17527     SemaRef.Diag(ELoc,
17528                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
17529         << ERange;
17530     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17531         << EnclosingExpr->getSourceRange();
17532     return true;
17533   }
17534 
17535   return FoundError;
17536 }
17537 
17538 // Look up the user-defined mapper given the mapper name and mapped type, and
17539 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)17540 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17541                                             CXXScopeSpec &MapperIdScopeSpec,
17542                                             const DeclarationNameInfo &MapperId,
17543                                             QualType Type,
17544                                             Expr *UnresolvedMapper) {
17545   if (MapperIdScopeSpec.isInvalid())
17546     return ExprError();
17547   // Get the actual type for the array type.
17548   if (Type->isArrayType()) {
17549     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
17550     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17551   }
17552   // Find all user-defined mappers with the given MapperId.
17553   SmallVector<UnresolvedSet<8>, 4> Lookups;
17554   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17555   Lookup.suppressDiagnostics();
17556   if (S) {
17557     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17558       NamedDecl *D = Lookup.getRepresentativeDecl();
17559       while (S && !S->isDeclScope(D))
17560         S = S->getParent();
17561       if (S)
17562         S = S->getParent();
17563       Lookups.emplace_back();
17564       Lookups.back().append(Lookup.begin(), Lookup.end());
17565       Lookup.clear();
17566     }
17567   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17568     // Extract the user-defined mappers with the given MapperId.
17569     Lookups.push_back(UnresolvedSet<8>());
17570     for (NamedDecl *D : ULE->decls()) {
17571       auto *DMD = cast<OMPDeclareMapperDecl>(D);
17572       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
17573       Lookups.back().addDecl(DMD);
17574     }
17575   }
17576   // Defer the lookup for dependent types. The results will be passed through
17577   // UnresolvedMapper on instantiation.
17578   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17579       Type->isInstantiationDependentType() ||
17580       Type->containsUnexpandedParameterPack() ||
17581       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17582         return !D->isInvalidDecl() &&
17583                (D->getType()->isDependentType() ||
17584                 D->getType()->isInstantiationDependentType() ||
17585                 D->getType()->containsUnexpandedParameterPack());
17586       })) {
17587     UnresolvedSet<8> URS;
17588     for (const UnresolvedSet<8> &Set : Lookups) {
17589       if (Set.empty())
17590         continue;
17591       URS.append(Set.begin(), Set.end());
17592     }
17593     return UnresolvedLookupExpr::Create(
17594         SemaRef.Context, /*NamingClass=*/nullptr,
17595         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17596         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17597   }
17598   SourceLocation Loc = MapperId.getLoc();
17599   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17600   //  The type must be of struct, union or class type in C and C++
17601   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17602       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17603     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17604     return ExprError();
17605   }
17606   // Perform argument dependent lookup.
17607   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17608     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17609   // Return the first user-defined mapper with the desired type.
17610   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17611           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17612             if (!D->isInvalidDecl() &&
17613                 SemaRef.Context.hasSameType(D->getType(), Type))
17614               return D;
17615             return nullptr;
17616           }))
17617     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17618   // Find the first user-defined mapper with a type derived from the desired
17619   // type.
17620   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17621           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17622             if (!D->isInvalidDecl() &&
17623                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17624                 !Type.isMoreQualifiedThan(D->getType()))
17625               return D;
17626             return nullptr;
17627           })) {
17628     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17629                        /*DetectVirtual=*/false);
17630     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17631       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17632               VD->getType().getUnqualifiedType()))) {
17633         if (SemaRef.CheckBaseClassAccess(
17634                 Loc, VD->getType(), Type, Paths.front(),
17635                 /*DiagID=*/0) != Sema::AR_inaccessible) {
17636           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17637         }
17638       }
17639     }
17640   }
17641   // Report error if a mapper is specified, but cannot be found.
17642   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17643     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17644         << Type << MapperId.getName();
17645     return ExprError();
17646   }
17647   return ExprEmpty();
17648 }
17649 
17650 namespace {
17651 // Utility struct that gathers all the related lists associated with a mappable
17652 // expression.
17653 struct MappableVarListInfo {
17654   // The list of expressions.
17655   ArrayRef<Expr *> VarList;
17656   // The list of processed expressions.
17657   SmallVector<Expr *, 16> ProcessedVarList;
17658   // The mappble components for each expression.
17659   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17660   // The base declaration of the variable.
17661   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17662   // The reference to the user-defined mapper associated with every expression.
17663   SmallVector<Expr *, 16> UDMapperList;
17664 
MappableVarListInfo__anon5b5425d04e11::MappableVarListInfo17665   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17666     // We have a list of components and base declarations for each entry in the
17667     // variable list.
17668     VarComponents.reserve(VarList.size());
17669     VarBaseDeclarations.reserve(VarList.size());
17670   }
17671 };
17672 }
17673 
17674 // Check the validity of the provided variable list for the provided clause kind
17675 // \a CKind. In the check process the valid expressions, mappable expression
17676 // components, variables, and user-defined mappers are extracted and used to
17677 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17678 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17679 // 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)17680 static void checkMappableExpressionList(
17681     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17682     MappableVarListInfo &MVLI, SourceLocation StartLoc,
17683     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17684     ArrayRef<Expr *> UnresolvedMappers,
17685     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17686     bool IsMapTypeImplicit = false) {
17687   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17688   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
17689          "Unexpected clause kind with mappable expressions!");
17690 
17691   // If the identifier of user-defined mapper is not specified, it is "default".
17692   // We do not change the actual name in this clause to distinguish whether a
17693   // mapper is specified explicitly, i.e., it is not explicitly specified when
17694   // MapperId.getName() is empty.
17695   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17696     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17697     MapperId.setName(DeclNames.getIdentifier(
17698         &SemaRef.getASTContext().Idents.get("default")));
17699     MapperId.setLoc(StartLoc);
17700   }
17701 
17702   // Iterators to find the current unresolved mapper expression.
17703   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17704   bool UpdateUMIt = false;
17705   Expr *UnresolvedMapper = nullptr;
17706 
17707   // Keep track of the mappable components and base declarations in this clause.
17708   // Each entry in the list is going to have a list of components associated. We
17709   // record each set of the components so that we can build the clause later on.
17710   // In the end we should have the same amount of declarations and component
17711   // lists.
17712 
17713   for (Expr *RE : MVLI.VarList) {
17714     assert(RE && "Null expr in omp to/from/map clause");
17715     SourceLocation ELoc = RE->getExprLoc();
17716 
17717     // Find the current unresolved mapper expression.
17718     if (UpdateUMIt && UMIt != UMEnd) {
17719       UMIt++;
17720       assert(
17721           UMIt != UMEnd &&
17722           "Expect the size of UnresolvedMappers to match with that of VarList");
17723     }
17724     UpdateUMIt = true;
17725     if (UMIt != UMEnd)
17726       UnresolvedMapper = *UMIt;
17727 
17728     const Expr *VE = RE->IgnoreParenLValueCasts();
17729 
17730     if (VE->isValueDependent() || VE->isTypeDependent() ||
17731         VE->isInstantiationDependent() ||
17732         VE->containsUnexpandedParameterPack()) {
17733       // Try to find the associated user-defined mapper.
17734       ExprResult ER = buildUserDefinedMapperRef(
17735           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17736           VE->getType().getCanonicalType(), UnresolvedMapper);
17737       if (ER.isInvalid())
17738         continue;
17739       MVLI.UDMapperList.push_back(ER.get());
17740       // We can only analyze this information once the missing information is
17741       // resolved.
17742       MVLI.ProcessedVarList.push_back(RE);
17743       continue;
17744     }
17745 
17746     Expr *SimpleExpr = RE->IgnoreParenCasts();
17747 
17748     if (!RE->isLValue()) {
17749       if (SemaRef.getLangOpts().OpenMP < 50) {
17750         SemaRef.Diag(
17751             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17752             << RE->getSourceRange();
17753       } else {
17754         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17755             << getOpenMPClauseName(CKind) << RE->getSourceRange();
17756       }
17757       continue;
17758     }
17759 
17760     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17761     ValueDecl *CurDeclaration = nullptr;
17762 
17763     // Obtain the array or member expression bases if required. Also, fill the
17764     // components array with all the components identified in the process.
17765     const Expr *BE = checkMapClauseExpressionBase(
17766         SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
17767         /*NoDiagnose=*/false);
17768     if (!BE)
17769       continue;
17770 
17771     assert(!CurComponents.empty() &&
17772            "Invalid mappable expression information.");
17773 
17774     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17775       // Add store "this" pointer to class in DSAStackTy for future checking
17776       DSAS->addMappedClassesQualTypes(TE->getType());
17777       // Try to find the associated user-defined mapper.
17778       ExprResult ER = buildUserDefinedMapperRef(
17779           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17780           VE->getType().getCanonicalType(), UnresolvedMapper);
17781       if (ER.isInvalid())
17782         continue;
17783       MVLI.UDMapperList.push_back(ER.get());
17784       // Skip restriction checking for variable or field declarations
17785       MVLI.ProcessedVarList.push_back(RE);
17786       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17787       MVLI.VarComponents.back().append(CurComponents.begin(),
17788                                        CurComponents.end());
17789       MVLI.VarBaseDeclarations.push_back(nullptr);
17790       continue;
17791     }
17792 
17793     // For the following checks, we rely on the base declaration which is
17794     // expected to be associated with the last component. The declaration is
17795     // expected to be a variable or a field (if 'this' is being mapped).
17796     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17797     assert(CurDeclaration && "Null decl on map clause.");
17798     assert(
17799         CurDeclaration->isCanonicalDecl() &&
17800         "Expecting components to have associated only canonical declarations.");
17801 
17802     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17803     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17804 
17805     assert((VD || FD) && "Only variables or fields are expected here!");
17806     (void)FD;
17807 
17808     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17809     // threadprivate variables cannot appear in a map clause.
17810     // OpenMP 4.5 [2.10.5, target update Construct]
17811     // threadprivate variables cannot appear in a from clause.
17812     if (VD && DSAS->isThreadPrivate(VD)) {
17813       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17814       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17815           << getOpenMPClauseName(CKind);
17816       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17817       continue;
17818     }
17819 
17820     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17821     //  A list item cannot appear in both a map clause and a data-sharing
17822     //  attribute clause on the same construct.
17823 
17824     // Check conflicts with other map clause expressions. We check the conflicts
17825     // with the current construct separately from the enclosing data
17826     // environment, because the restrictions are different. We only have to
17827     // check conflicts across regions for the map clauses.
17828     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17829                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
17830       break;
17831     if (CKind == OMPC_map &&
17832         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17833         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17834                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
17835       break;
17836 
17837     // OpenMP 4.5 [2.10.5, target update Construct]
17838     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17839     //  If the type of a list item is a reference to a type T then the type will
17840     //  be considered to be T for all purposes of this clause.
17841     auto I = llvm::find_if(
17842         CurComponents,
17843         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17844           return MC.getAssociatedDeclaration();
17845         });
17846     assert(I != CurComponents.end() && "Null decl on map clause.");
17847     QualType Type;
17848     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17849     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17850     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17851     if (ASE) {
17852       Type = ASE->getType().getNonReferenceType();
17853     } else if (OASE) {
17854       QualType BaseType =
17855           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17856       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17857         Type = ATy->getElementType();
17858       else
17859         Type = BaseType->getPointeeType();
17860       Type = Type.getNonReferenceType();
17861     } else if (OAShE) {
17862       Type = OAShE->getBase()->getType()->getPointeeType();
17863     } else {
17864       Type = VE->getType();
17865     }
17866 
17867     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17868     // A list item in a to or from clause must have a mappable type.
17869     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17870     //  A list item must have a mappable type.
17871     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17872                            DSAS, Type))
17873       continue;
17874 
17875     Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17876 
17877     if (CKind == OMPC_map) {
17878       // target enter data
17879       // OpenMP [2.10.2, Restrictions, p. 99]
17880       // A map-type must be specified in all map clauses and must be either
17881       // to or alloc.
17882       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17883       if (DKind == OMPD_target_enter_data &&
17884           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17885         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17886             << (IsMapTypeImplicit ? 1 : 0)
17887             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17888             << getOpenMPDirectiveName(DKind);
17889         continue;
17890       }
17891 
17892       // target exit_data
17893       // OpenMP [2.10.3, Restrictions, p. 102]
17894       // A map-type must be specified in all map clauses and must be either
17895       // from, release, or delete.
17896       if (DKind == OMPD_target_exit_data &&
17897           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17898             MapType == OMPC_MAP_delete)) {
17899         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17900             << (IsMapTypeImplicit ? 1 : 0)
17901             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17902             << getOpenMPDirectiveName(DKind);
17903         continue;
17904       }
17905 
17906       // target, target data
17907       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17908       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17909       // A map-type in a map clause must be to, from, tofrom or alloc
17910       if ((DKind == OMPD_target_data ||
17911            isOpenMPTargetExecutionDirective(DKind)) &&
17912           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17913             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17914         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17915             << (IsMapTypeImplicit ? 1 : 0)
17916             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17917             << getOpenMPDirectiveName(DKind);
17918         continue;
17919       }
17920 
17921       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17922       // A list item cannot appear in both a map clause and a data-sharing
17923       // attribute clause on the same construct
17924       //
17925       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17926       // A list item cannot appear in both a map clause and a data-sharing
17927       // attribute clause on the same construct unless the construct is a
17928       // combined construct.
17929       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17930                   isOpenMPTargetExecutionDirective(DKind)) ||
17931                  DKind == OMPD_target)) {
17932         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17933         if (isOpenMPPrivate(DVar.CKind)) {
17934           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17935               << getOpenMPClauseName(DVar.CKind)
17936               << getOpenMPClauseName(OMPC_map)
17937               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17938           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17939           continue;
17940         }
17941       }
17942     }
17943 
17944     // Try to find the associated user-defined mapper.
17945     ExprResult ER = buildUserDefinedMapperRef(
17946         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17947         Type.getCanonicalType(), UnresolvedMapper);
17948     if (ER.isInvalid())
17949       continue;
17950     MVLI.UDMapperList.push_back(ER.get());
17951 
17952     // Save the current expression.
17953     MVLI.ProcessedVarList.push_back(RE);
17954 
17955     // Store the components in the stack so that they can be used to check
17956     // against other clauses later on.
17957     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17958                                           /*WhereFoundClauseKind=*/OMPC_map);
17959 
17960     // Save the components and declaration to create the clause. For purposes of
17961     // the clause creation, any component list that has has base 'this' uses
17962     // null as base declaration.
17963     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17964     MVLI.VarComponents.back().append(CurComponents.begin(),
17965                                      CurComponents.end());
17966     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17967                                                            : CurDeclaration);
17968   }
17969 }
17970 
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)17971 OMPClause *Sema::ActOnOpenMPMapClause(
17972     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17973     ArrayRef<SourceLocation> MapTypeModifiersLoc,
17974     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17975     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17976     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17977     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17978   OpenMPMapModifierKind Modifiers[] = {
17979       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17980       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17981   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17982 
17983   // Process map-type-modifiers, flag errors for duplicate modifiers.
17984   unsigned Count = 0;
17985   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17986     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17987         llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17988       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17989       continue;
17990     }
17991     assert(Count < NumberOfOMPMapClauseModifiers &&
17992            "Modifiers exceed the allowed number of map type modifiers");
17993     Modifiers[Count] = MapTypeModifiers[I];
17994     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17995     ++Count;
17996   }
17997 
17998   MappableVarListInfo MVLI(VarList);
17999   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
18000                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
18001                               MapType, IsMapTypeImplicit);
18002 
18003   // We need to produce a map clause even if we don't have variables so that
18004   // other diagnostics related with non-existing map clauses are accurate.
18005   return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
18006                               MVLI.VarBaseDeclarations, MVLI.VarComponents,
18007                               MVLI.UDMapperList, Modifiers, ModifiersLoc,
18008                               MapperIdScopeSpec.getWithLocInContext(Context),
18009                               MapperId, MapType, IsMapTypeImplicit, MapLoc);
18010 }
18011 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)18012 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
18013                                                TypeResult ParsedType) {
18014   assert(ParsedType.isUsable());
18015 
18016   QualType ReductionType = GetTypeFromParser(ParsedType.get());
18017   if (ReductionType.isNull())
18018     return QualType();
18019 
18020   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
18021   // A type name in a declare reduction directive cannot be a function type, an
18022   // array type, a reference type, or a type qualified with const, volatile or
18023   // restrict.
18024   if (ReductionType.hasQualifiers()) {
18025     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
18026     return QualType();
18027   }
18028 
18029   if (ReductionType->isFunctionType()) {
18030     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
18031     return QualType();
18032   }
18033   if (ReductionType->isReferenceType()) {
18034     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
18035     return QualType();
18036   }
18037   if (ReductionType->isArrayType()) {
18038     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
18039     return QualType();
18040   }
18041   return ReductionType;
18042 }
18043 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)18044 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
18045     Scope *S, DeclContext *DC, DeclarationName Name,
18046     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
18047     AccessSpecifier AS, Decl *PrevDeclInScope) {
18048   SmallVector<Decl *, 8> Decls;
18049   Decls.reserve(ReductionTypes.size());
18050 
18051   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
18052                       forRedeclarationInCurContext());
18053   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
18054   // A reduction-identifier may not be re-declared in the current scope for the
18055   // same type or for a type that is compatible according to the base language
18056   // rules.
18057   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18058   OMPDeclareReductionDecl *PrevDRD = nullptr;
18059   bool InCompoundScope = true;
18060   if (S != nullptr) {
18061     // Find previous declaration with the same name not referenced in other
18062     // declarations.
18063     FunctionScopeInfo *ParentFn = getEnclosingFunction();
18064     InCompoundScope =
18065         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18066     LookupName(Lookup, S);
18067     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18068                          /*AllowInlineNamespace=*/false);
18069     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
18070     LookupResult::Filter Filter = Lookup.makeFilter();
18071     while (Filter.hasNext()) {
18072       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
18073       if (InCompoundScope) {
18074         auto I = UsedAsPrevious.find(PrevDecl);
18075         if (I == UsedAsPrevious.end())
18076           UsedAsPrevious[PrevDecl] = false;
18077         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
18078           UsedAsPrevious[D] = true;
18079       }
18080       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18081           PrevDecl->getLocation();
18082     }
18083     Filter.done();
18084     if (InCompoundScope) {
18085       for (const auto &PrevData : UsedAsPrevious) {
18086         if (!PrevData.second) {
18087           PrevDRD = PrevData.first;
18088           break;
18089         }
18090       }
18091     }
18092   } else if (PrevDeclInScope != nullptr) {
18093     auto *PrevDRDInScope = PrevDRD =
18094         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
18095     do {
18096       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
18097           PrevDRDInScope->getLocation();
18098       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
18099     } while (PrevDRDInScope != nullptr);
18100   }
18101   for (const auto &TyData : ReductionTypes) {
18102     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
18103     bool Invalid = false;
18104     if (I != PreviousRedeclTypes.end()) {
18105       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
18106           << TyData.first;
18107       Diag(I->second, diag::note_previous_definition);
18108       Invalid = true;
18109     }
18110     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
18111     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
18112                                                 Name, TyData.first, PrevDRD);
18113     DC->addDecl(DRD);
18114     DRD->setAccess(AS);
18115     Decls.push_back(DRD);
18116     if (Invalid)
18117       DRD->setInvalidDecl();
18118     else
18119       PrevDRD = DRD;
18120   }
18121 
18122   return DeclGroupPtrTy::make(
18123       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
18124 }
18125 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)18126 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
18127   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18128 
18129   // Enter new function scope.
18130   PushFunctionScope();
18131   setFunctionHasBranchProtectedScope();
18132   getCurFunction()->setHasOMPDeclareReductionCombiner();
18133 
18134   if (S != nullptr)
18135     PushDeclContext(S, DRD);
18136   else
18137     CurContext = DRD;
18138 
18139   PushExpressionEvaluationContext(
18140       ExpressionEvaluationContext::PotentiallyEvaluated);
18141 
18142   QualType ReductionType = DRD->getType();
18143   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
18144   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
18145   // uses semantics of argument handles by value, but it should be passed by
18146   // reference. C lang does not support references, so pass all parameters as
18147   // pointers.
18148   // Create 'T omp_in;' variable.
18149   VarDecl *OmpInParm =
18150       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
18151   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
18152   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
18153   // uses semantics of argument handles by value, but it should be passed by
18154   // reference. C lang does not support references, so pass all parameters as
18155   // pointers.
18156   // Create 'T omp_out;' variable.
18157   VarDecl *OmpOutParm =
18158       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
18159   if (S != nullptr) {
18160     PushOnScopeChains(OmpInParm, S);
18161     PushOnScopeChains(OmpOutParm, S);
18162   } else {
18163     DRD->addDecl(OmpInParm);
18164     DRD->addDecl(OmpOutParm);
18165   }
18166   Expr *InE =
18167       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
18168   Expr *OutE =
18169       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
18170   DRD->setCombinerData(InE, OutE);
18171 }
18172 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)18173 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
18174   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18175   DiscardCleanupsInEvaluationContext();
18176   PopExpressionEvaluationContext();
18177 
18178   PopDeclContext();
18179   PopFunctionScopeInfo();
18180 
18181   if (Combiner != nullptr)
18182     DRD->setCombiner(Combiner);
18183   else
18184     DRD->setInvalidDecl();
18185 }
18186 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)18187 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
18188   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18189 
18190   // Enter new function scope.
18191   PushFunctionScope();
18192   setFunctionHasBranchProtectedScope();
18193 
18194   if (S != nullptr)
18195     PushDeclContext(S, DRD);
18196   else
18197     CurContext = DRD;
18198 
18199   PushExpressionEvaluationContext(
18200       ExpressionEvaluationContext::PotentiallyEvaluated);
18201 
18202   QualType ReductionType = DRD->getType();
18203   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18204   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18205   // uses semantics of argument handles by value, but it should be passed by
18206   // reference. C lang does not support references, so pass all parameters as
18207   // pointers.
18208   // Create 'T omp_priv;' variable.
18209   VarDecl *OmpPrivParm =
18210       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18211   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18212   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18213   // uses semantics of argument handles by value, but it should be passed by
18214   // reference. C lang does not support references, so pass all parameters as
18215   // pointers.
18216   // Create 'T omp_orig;' variable.
18217   VarDecl *OmpOrigParm =
18218       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18219   if (S != nullptr) {
18220     PushOnScopeChains(OmpPrivParm, S);
18221     PushOnScopeChains(OmpOrigParm, S);
18222   } else {
18223     DRD->addDecl(OmpPrivParm);
18224     DRD->addDecl(OmpOrigParm);
18225   }
18226   Expr *OrigE =
18227       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18228   Expr *PrivE =
18229       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18230   DRD->setInitializerData(OrigE, PrivE);
18231   return OmpPrivParm;
18232 }
18233 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)18234 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18235                                                      VarDecl *OmpPrivParm) {
18236   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18237   DiscardCleanupsInEvaluationContext();
18238   PopExpressionEvaluationContext();
18239 
18240   PopDeclContext();
18241   PopFunctionScopeInfo();
18242 
18243   if (Initializer != nullptr) {
18244     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18245   } else if (OmpPrivParm->hasInit()) {
18246     DRD->setInitializer(OmpPrivParm->getInit(),
18247                         OmpPrivParm->isDirectInit()
18248                             ? OMPDeclareReductionDecl::DirectInit
18249                             : OMPDeclareReductionDecl::CopyInit);
18250   } else {
18251     DRD->setInvalidDecl();
18252   }
18253 }
18254 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)18255 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18256     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18257   for (Decl *D : DeclReductions.get()) {
18258     if (IsValid) {
18259       if (S)
18260         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18261                           /*AddToContext=*/false);
18262     } else {
18263       D->setInvalidDecl();
18264     }
18265   }
18266   return DeclReductions;
18267 }
18268 
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)18269 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18270   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18271   QualType T = TInfo->getType();
18272   if (D.isInvalidType())
18273     return true;
18274 
18275   if (getLangOpts().CPlusPlus) {
18276     // Check that there are no default arguments (C++ only).
18277     CheckExtraCXXDefaultArguments(D);
18278   }
18279 
18280   return CreateParsedType(T, TInfo);
18281 }
18282 
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)18283 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18284                                             TypeResult ParsedType) {
18285   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
18286 
18287   QualType MapperType = GetTypeFromParser(ParsedType.get());
18288   assert(!MapperType.isNull() && "Expect valid mapper type");
18289 
18290   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18291   //  The type must be of struct, union or class type in C and C++
18292   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18293     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18294     return QualType();
18295   }
18296   return MapperType;
18297 }
18298 
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)18299 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18300     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18301     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18302     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18303   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18304                       forRedeclarationInCurContext());
18305   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18306   //  A mapper-identifier may not be redeclared in the current scope for the
18307   //  same type or for a type that is compatible according to the base language
18308   //  rules.
18309   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18310   OMPDeclareMapperDecl *PrevDMD = nullptr;
18311   bool InCompoundScope = true;
18312   if (S != nullptr) {
18313     // Find previous declaration with the same name not referenced in other
18314     // declarations.
18315     FunctionScopeInfo *ParentFn = getEnclosingFunction();
18316     InCompoundScope =
18317         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18318     LookupName(Lookup, S);
18319     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18320                          /*AllowInlineNamespace=*/false);
18321     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18322     LookupResult::Filter Filter = Lookup.makeFilter();
18323     while (Filter.hasNext()) {
18324       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18325       if (InCompoundScope) {
18326         auto I = UsedAsPrevious.find(PrevDecl);
18327         if (I == UsedAsPrevious.end())
18328           UsedAsPrevious[PrevDecl] = false;
18329         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18330           UsedAsPrevious[D] = true;
18331       }
18332       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18333           PrevDecl->getLocation();
18334     }
18335     Filter.done();
18336     if (InCompoundScope) {
18337       for (const auto &PrevData : UsedAsPrevious) {
18338         if (!PrevData.second) {
18339           PrevDMD = PrevData.first;
18340           break;
18341         }
18342       }
18343     }
18344   } else if (PrevDeclInScope) {
18345     auto *PrevDMDInScope = PrevDMD =
18346         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18347     do {
18348       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18349           PrevDMDInScope->getLocation();
18350       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18351     } while (PrevDMDInScope != nullptr);
18352   }
18353   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18354   bool Invalid = false;
18355   if (I != PreviousRedeclTypes.end()) {
18356     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18357         << MapperType << Name;
18358     Diag(I->second, diag::note_previous_definition);
18359     Invalid = true;
18360   }
18361   auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18362                                            MapperType, VN, Clauses, PrevDMD);
18363   if (S)
18364     PushOnScopeChains(DMD, S);
18365   else
18366     DC->addDecl(DMD);
18367   DMD->setAccess(AS);
18368   if (Invalid)
18369     DMD->setInvalidDecl();
18370 
18371   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18372   VD->setDeclContext(DMD);
18373   VD->setLexicalDeclContext(DMD);
18374   DMD->addDecl(VD);
18375   DMD->setMapperVarRef(MapperVarRef);
18376 
18377   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18378 }
18379 
18380 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)18381 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18382                                                SourceLocation StartLoc,
18383                                                DeclarationName VN) {
18384   TypeSourceInfo *TInfo =
18385       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18386   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18387                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18388                              MapperType, TInfo, SC_None);
18389   if (S)
18390     PushOnScopeChains(VD, S, /*AddToContext=*/false);
18391   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18392   DSAStack->addDeclareMapperVarRef(E);
18393   return E;
18394 }
18395 
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const18396 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18397   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18398   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
18399   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18400     return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18401   return true;
18402 }
18403 
getOpenMPDeclareMapperVarName() const18404 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18405   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18406   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
18407 }
18408 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18409 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18410                                            SourceLocation StartLoc,
18411                                            SourceLocation LParenLoc,
18412                                            SourceLocation EndLoc) {
18413   Expr *ValExpr = NumTeams;
18414   Stmt *HelperValStmt = nullptr;
18415 
18416   // OpenMP [teams Constrcut, Restrictions]
18417   // The num_teams expression must evaluate to a positive integer value.
18418   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18419                                  /*StrictlyPositive=*/true))
18420     return nullptr;
18421 
18422   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18423   OpenMPDirectiveKind CaptureRegion =
18424       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18425   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18426     ValExpr = MakeFullExpr(ValExpr).get();
18427     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18428     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18429     HelperValStmt = buildPreInits(Context, Captures);
18430   }
18431 
18432   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18433                                          StartLoc, LParenLoc, EndLoc);
18434 }
18435 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18436 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18437                                               SourceLocation StartLoc,
18438                                               SourceLocation LParenLoc,
18439                                               SourceLocation EndLoc) {
18440   Expr *ValExpr = ThreadLimit;
18441   Stmt *HelperValStmt = nullptr;
18442 
18443   // OpenMP [teams Constrcut, Restrictions]
18444   // The thread_limit expression must evaluate to a positive integer value.
18445   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18446                                  /*StrictlyPositive=*/true))
18447     return nullptr;
18448 
18449   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18450   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18451       DKind, OMPC_thread_limit, LangOpts.OpenMP);
18452   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18453     ValExpr = MakeFullExpr(ValExpr).get();
18454     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18455     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18456     HelperValStmt = buildPreInits(Context, Captures);
18457   }
18458 
18459   return new (Context) OMPThreadLimitClause(
18460       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18461 }
18462 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18463 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18464                                            SourceLocation StartLoc,
18465                                            SourceLocation LParenLoc,
18466                                            SourceLocation EndLoc) {
18467   Expr *ValExpr = Priority;
18468   Stmt *HelperValStmt = nullptr;
18469   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18470 
18471   // OpenMP [2.9.1, task Constrcut]
18472   // The priority-value is a non-negative numerical scalar expression.
18473   if (!isNonNegativeIntegerValue(
18474           ValExpr, *this, OMPC_priority,
18475           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18476           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18477     return nullptr;
18478 
18479   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18480                                          StartLoc, LParenLoc, EndLoc);
18481 }
18482 
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18483 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18484                                             SourceLocation StartLoc,
18485                                             SourceLocation LParenLoc,
18486                                             SourceLocation EndLoc) {
18487   Expr *ValExpr = Grainsize;
18488   Stmt *HelperValStmt = nullptr;
18489   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18490 
18491   // OpenMP [2.9.2, taskloop Constrcut]
18492   // The parameter of the grainsize clause must be a positive integer
18493   // expression.
18494   if (!isNonNegativeIntegerValue(
18495           ValExpr, *this, OMPC_grainsize,
18496           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18497           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18498     return nullptr;
18499 
18500   return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18501                                           StartLoc, LParenLoc, EndLoc);
18502 }
18503 
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18504 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18505                                            SourceLocation StartLoc,
18506                                            SourceLocation LParenLoc,
18507                                            SourceLocation EndLoc) {
18508   Expr *ValExpr = NumTasks;
18509   Stmt *HelperValStmt = nullptr;
18510   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18511 
18512   // OpenMP [2.9.2, taskloop Constrcut]
18513   // The parameter of the num_tasks clause must be a positive integer
18514   // expression.
18515   if (!isNonNegativeIntegerValue(
18516           ValExpr, *this, OMPC_num_tasks,
18517           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18518           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18519     return nullptr;
18520 
18521   return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18522                                          StartLoc, LParenLoc, EndLoc);
18523 }
18524 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18525 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18526                                        SourceLocation LParenLoc,
18527                                        SourceLocation EndLoc) {
18528   // OpenMP [2.13.2, critical construct, Description]
18529   // ... where hint-expression is an integer constant expression that evaluates
18530   // to a valid lock hint.
18531   ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18532   if (HintExpr.isInvalid())
18533     return nullptr;
18534   return new (Context)
18535       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18536 }
18537 
18538 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)18539 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18540                                 DSAStackTy *Stack) {
18541   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18542   if (!OMPEventHandleT.isNull())
18543     return true;
18544   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18545   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18546   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18547     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18548     return false;
18549   }
18550   Stack->setOMPEventHandleT(PT.get());
18551   return true;
18552 }
18553 
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18554 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18555                                          SourceLocation LParenLoc,
18556                                          SourceLocation EndLoc) {
18557   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18558       !Evt->isInstantiationDependent() &&
18559       !Evt->containsUnexpandedParameterPack()) {
18560     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
18561       return nullptr;
18562     // OpenMP 5.0, 2.10.1 task Construct.
18563     // event-handle is a variable of the omp_event_handle_t type.
18564     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18565     if (!Ref) {
18566       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18567           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18568       return nullptr;
18569     }
18570     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18571     if (!VD) {
18572       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18573           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18574       return nullptr;
18575     }
18576     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
18577                                         VD->getType()) ||
18578         VD->getType().isConstant(Context)) {
18579       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18580           << "omp_event_handle_t" << 1 << VD->getType()
18581           << Evt->getSourceRange();
18582       return nullptr;
18583     }
18584     // OpenMP 5.0, 2.10.1 task Construct
18585     // [detach clause]... The event-handle will be considered as if it was
18586     // specified on a firstprivate clause.
18587     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
18588     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18589         DVar.RefExpr) {
18590       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18591           << getOpenMPClauseName(DVar.CKind)
18592           << getOpenMPClauseName(OMPC_firstprivate);
18593       reportOriginalDsa(*this, DSAStack, VD, DVar);
18594       return nullptr;
18595     }
18596   }
18597 
18598   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18599 }
18600 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)18601 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18602     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18603     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18604     SourceLocation EndLoc) {
18605   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18606     std::string Values;
18607     Values += "'";
18608     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18609     Values += "'";
18610     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18611         << Values << getOpenMPClauseName(OMPC_dist_schedule);
18612     return nullptr;
18613   }
18614   Expr *ValExpr = ChunkSize;
18615   Stmt *HelperValStmt = nullptr;
18616   if (ChunkSize) {
18617     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18618         !ChunkSize->isInstantiationDependent() &&
18619         !ChunkSize->containsUnexpandedParameterPack()) {
18620       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18621       ExprResult Val =
18622           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18623       if (Val.isInvalid())
18624         return nullptr;
18625 
18626       ValExpr = Val.get();
18627 
18628       // OpenMP [2.7.1, Restrictions]
18629       //  chunk_size must be a loop invariant integer expression with a positive
18630       //  value.
18631       if (Optional<llvm::APSInt> Result =
18632               ValExpr->getIntegerConstantExpr(Context)) {
18633         if (Result->isSigned() && !Result->isStrictlyPositive()) {
18634           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18635               << "dist_schedule" << ChunkSize->getSourceRange();
18636           return nullptr;
18637         }
18638       } else if (getOpenMPCaptureRegionForClause(
18639                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
18640                      LangOpts.OpenMP) != OMPD_unknown &&
18641                  !CurContext->isDependentContext()) {
18642         ValExpr = MakeFullExpr(ValExpr).get();
18643         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18644         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18645         HelperValStmt = buildPreInits(Context, Captures);
18646       }
18647     }
18648   }
18649 
18650   return new (Context)
18651       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18652                             Kind, ValExpr, HelperValStmt);
18653 }
18654 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)18655 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18656     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18657     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18658     SourceLocation KindLoc, SourceLocation EndLoc) {
18659   if (getLangOpts().OpenMP < 50) {
18660     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18661         Kind != OMPC_DEFAULTMAP_scalar) {
18662       std::string Value;
18663       SourceLocation Loc;
18664       Value += "'";
18665       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18666         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18667                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
18668         Loc = MLoc;
18669       } else {
18670         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18671                                                OMPC_DEFAULTMAP_scalar);
18672         Loc = KindLoc;
18673       }
18674       Value += "'";
18675       Diag(Loc, diag::err_omp_unexpected_clause_value)
18676           << Value << getOpenMPClauseName(OMPC_defaultmap);
18677       return nullptr;
18678     }
18679   } else {
18680     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18681     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18682                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18683     if (!isDefaultmapKind || !isDefaultmapModifier) {
18684       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
18685       if (LangOpts.OpenMP == 50) {
18686         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18687                                   "'firstprivate', 'none', 'default'";
18688         if (!isDefaultmapKind && isDefaultmapModifier) {
18689           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18690               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18691         } else if (isDefaultmapKind && !isDefaultmapModifier) {
18692           Diag(MLoc, diag::err_omp_unexpected_clause_value)
18693               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18694         } else {
18695           Diag(MLoc, diag::err_omp_unexpected_clause_value)
18696               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18697           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18698               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18699         }
18700       } else {
18701         StringRef ModifierValue =
18702             "'alloc', 'from', 'to', 'tofrom', "
18703             "'firstprivate', 'none', 'default', 'present'";
18704         if (!isDefaultmapKind && isDefaultmapModifier) {
18705           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18706               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18707         } else if (isDefaultmapKind && !isDefaultmapModifier) {
18708           Diag(MLoc, diag::err_omp_unexpected_clause_value)
18709               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18710         } else {
18711           Diag(MLoc, diag::err_omp_unexpected_clause_value)
18712               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18713           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18714               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18715         }
18716       }
18717       return nullptr;
18718     }
18719 
18720     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18721     //  At most one defaultmap clause for each category can appear on the
18722     //  directive.
18723     if (DSAStack->checkDefaultmapCategory(Kind)) {
18724       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18725       return nullptr;
18726     }
18727   }
18728   if (Kind == OMPC_DEFAULTMAP_unknown) {
18729     // Variable category is not specified - mark all categories.
18730     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18731     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18732     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18733   } else {
18734     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
18735   }
18736 
18737   return new (Context)
18738       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18739 }
18740 
ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)18741 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18742   DeclContext *CurLexicalContext = getCurLexicalContext();
18743   if (!CurLexicalContext->isFileContext() &&
18744       !CurLexicalContext->isExternCContext() &&
18745       !CurLexicalContext->isExternCXXContext() &&
18746       !isa<CXXRecordDecl>(CurLexicalContext) &&
18747       !isa<ClassTemplateDecl>(CurLexicalContext) &&
18748       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18749       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18750     Diag(Loc, diag::err_omp_region_not_file_context);
18751     return false;
18752   }
18753   DeclareTargetNesting.push_back(Loc);
18754   return true;
18755 }
18756 
ActOnFinishOpenMPDeclareTargetDirective()18757 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18758   assert(!DeclareTargetNesting.empty() &&
18759          "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
18760   DeclareTargetNesting.pop_back();
18761 }
18762 
18763 NamedDecl *
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,NamedDeclSetType & SameDirectiveDecls)18764 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18765                                     const DeclarationNameInfo &Id,
18766                                     NamedDeclSetType &SameDirectiveDecls) {
18767   LookupResult Lookup(*this, Id, LookupOrdinaryName);
18768   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18769 
18770   if (Lookup.isAmbiguous())
18771     return nullptr;
18772   Lookup.suppressDiagnostics();
18773 
18774   if (!Lookup.isSingleResult()) {
18775     VarOrFuncDeclFilterCCC CCC(*this);
18776     if (TypoCorrection Corrected =
18777             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18778                         CTK_ErrorRecovery)) {
18779       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18780                                   << Id.getName());
18781       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18782       return nullptr;
18783     }
18784 
18785     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18786     return nullptr;
18787   }
18788 
18789   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18790   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18791       !isa<FunctionTemplateDecl>(ND)) {
18792     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18793     return nullptr;
18794   }
18795   if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18796     Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18797   return ND;
18798 }
18799 
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)18800 void Sema::ActOnOpenMPDeclareTargetName(
18801     NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18802     OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18803   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
18804           isa<FunctionTemplateDecl>(ND)) &&
18805          "Expected variable, function or function template.");
18806 
18807   // Diagnose marking after use as it may lead to incorrect diagnosis and
18808   // codegen.
18809   if (LangOpts.OpenMP >= 50 &&
18810       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18811     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18812 
18813   auto *VD = cast<ValueDecl>(ND);
18814   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18815       OMPDeclareTargetDeclAttr::getDeviceType(VD);
18816   Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
18817   if (DevTy.hasValue() && *DevTy != DT &&
18818       (DeclareTargetNesting.empty() ||
18819        *AttrLoc != DeclareTargetNesting.back())) {
18820     Diag(Loc, diag::err_omp_device_type_mismatch)
18821         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18822         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18823     return;
18824   }
18825   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18826       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18827   if (!Res || (!DeclareTargetNesting.empty() &&
18828                *AttrLoc == DeclareTargetNesting.back())) {
18829     auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18830         Context, MT, DT, DeclareTargetNesting.size() + 1,
18831         SourceRange(Loc, Loc));
18832     ND->addAttr(A);
18833     if (ASTMutationListener *ML = Context.getASTMutationListener())
18834       ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18835     checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18836   } else if (*Res != MT) {
18837     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18838   }
18839 }
18840 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)18841 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18842                                      Sema &SemaRef, Decl *D) {
18843   if (!D || !isa<VarDecl>(D))
18844     return;
18845   auto *VD = cast<VarDecl>(D);
18846   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18847       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18848   if (SemaRef.LangOpts.OpenMP >= 50 &&
18849       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18850        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18851       VD->hasGlobalStorage()) {
18852     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18853         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18854     if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18855       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18856       // If a lambda declaration and definition appears between a
18857       // declare target directive and the matching end declare target
18858       // directive, all variables that are captured by the lambda
18859       // expression must also appear in a to clause.
18860       SemaRef.Diag(VD->getLocation(),
18861                    diag::err_omp_lambda_capture_in_declare_target_not_to);
18862       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18863           << VD << 0 << SR;
18864       return;
18865     }
18866   }
18867   if (MapTy.hasValue())
18868     return;
18869   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18870   SemaRef.Diag(SL, diag::note_used_here) << SR;
18871 }
18872 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)18873 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18874                                    Sema &SemaRef, DSAStackTy *Stack,
18875                                    ValueDecl *VD) {
18876   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18877          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18878                            /*FullCheck=*/false);
18879 }
18880 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)18881 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18882                                             SourceLocation IdLoc) {
18883   if (!D || D->isInvalidDecl())
18884     return;
18885   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18886   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18887   if (auto *VD = dyn_cast<VarDecl>(D)) {
18888     // Only global variables can be marked as declare target.
18889     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18890         !VD->isStaticDataMember())
18891       return;
18892     // 2.10.6: threadprivate variable cannot appear in a declare target
18893     // directive.
18894     if (DSAStack->isThreadPrivate(VD)) {
18895       Diag(SL, diag::err_omp_threadprivate_in_target);
18896       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
18897       return;
18898     }
18899   }
18900   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18901     D = FTD->getTemplatedDecl();
18902   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18903     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18904         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18905     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18906       Diag(IdLoc, diag::err_omp_function_in_link_clause);
18907       Diag(FD->getLocation(), diag::note_defined_here) << FD;
18908       return;
18909     }
18910   }
18911   if (auto *VD = dyn_cast<ValueDecl>(D)) {
18912     // Problem if any with var declared with incomplete type will be reported
18913     // as normal, so no need to check it here.
18914     if ((E || !VD->getType()->isIncompleteType()) &&
18915         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
18916       return;
18917     if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18918       // Checking declaration inside declare target region.
18919       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18920           isa<FunctionTemplateDecl>(D)) {
18921         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18922             Context, OMPDeclareTargetDeclAttr::MT_To,
18923             OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
18924             SourceRange(DeclareTargetNesting.back(),
18925                         DeclareTargetNesting.back()));
18926         D->addAttr(A);
18927         if (ASTMutationListener *ML = Context.getASTMutationListener())
18928           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18929       }
18930       return;
18931     }
18932   }
18933   if (!E)
18934     return;
18935   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18936 }
18937 
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)18938 OMPClause *Sema::ActOnOpenMPToClause(
18939     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18940     ArrayRef<SourceLocation> MotionModifiersLoc,
18941     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18942     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18943     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18944   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18945                                           OMPC_MOTION_MODIFIER_unknown};
18946   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18947 
18948   // Process motion-modifiers, flag errors for duplicate modifiers.
18949   unsigned Count = 0;
18950   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18951     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18952         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18953       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18954       continue;
18955     }
18956     assert(Count < NumberOfOMPMotionModifiers &&
18957            "Modifiers exceed the allowed number of motion modifiers");
18958     Modifiers[Count] = MotionModifiers[I];
18959     ModifiersLoc[Count] = MotionModifiersLoc[I];
18960     ++Count;
18961   }
18962 
18963   MappableVarListInfo MVLI(VarList);
18964   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
18965                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
18966   if (MVLI.ProcessedVarList.empty())
18967     return nullptr;
18968 
18969   return OMPToClause::Create(
18970       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18971       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18972       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18973 }
18974 
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)18975 OMPClause *Sema::ActOnOpenMPFromClause(
18976     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18977     ArrayRef<SourceLocation> MotionModifiersLoc,
18978     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18979     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18980     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18981   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18982                                           OMPC_MOTION_MODIFIER_unknown};
18983   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18984 
18985   // Process motion-modifiers, flag errors for duplicate modifiers.
18986   unsigned Count = 0;
18987   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18988     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18989         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18990       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18991       continue;
18992     }
18993     assert(Count < NumberOfOMPMotionModifiers &&
18994            "Modifiers exceed the allowed number of motion modifiers");
18995     Modifiers[Count] = MotionModifiers[I];
18996     ModifiersLoc[Count] = MotionModifiersLoc[I];
18997     ++Count;
18998   }
18999 
19000   MappableVarListInfo MVLI(VarList);
19001   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
19002                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
19003   if (MVLI.ProcessedVarList.empty())
19004     return nullptr;
19005 
19006   return OMPFromClause::Create(
19007       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
19008       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
19009       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
19010 }
19011 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)19012 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
19013                                                const OMPVarListLocTy &Locs) {
19014   MappableVarListInfo MVLI(VarList);
19015   SmallVector<Expr *, 8> PrivateCopies;
19016   SmallVector<Expr *, 8> Inits;
19017 
19018   for (Expr *RefExpr : VarList) {
19019     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
19020     SourceLocation ELoc;
19021     SourceRange ERange;
19022     Expr *SimpleRefExpr = RefExpr;
19023     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19024     if (Res.second) {
19025       // It will be analyzed later.
19026       MVLI.ProcessedVarList.push_back(RefExpr);
19027       PrivateCopies.push_back(nullptr);
19028       Inits.push_back(nullptr);
19029     }
19030     ValueDecl *D = Res.first;
19031     if (!D)
19032       continue;
19033 
19034     QualType Type = D->getType();
19035     Type = Type.getNonReferenceType().getUnqualifiedType();
19036 
19037     auto *VD = dyn_cast<VarDecl>(D);
19038 
19039     // Item should be a pointer or reference to pointer.
19040     if (!Type->isPointerType()) {
19041       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
19042           << 0 << RefExpr->getSourceRange();
19043       continue;
19044     }
19045 
19046     // Build the private variable and the expression that refers to it.
19047     auto VDPrivate =
19048         buildVarDecl(*this, ELoc, Type, D->getName(),
19049                      D->hasAttrs() ? &D->getAttrs() : nullptr,
19050                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19051     if (VDPrivate->isInvalidDecl())
19052       continue;
19053 
19054     CurContext->addDecl(VDPrivate);
19055     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
19056         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
19057 
19058     // Add temporary variable to initialize the private copy of the pointer.
19059     VarDecl *VDInit =
19060         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
19061     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
19062         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
19063     AddInitializerToDecl(VDPrivate,
19064                          DefaultLvalueConversion(VDInitRefExpr).get(),
19065                          /*DirectInit=*/false);
19066 
19067     // If required, build a capture to implement the privatization initialized
19068     // with the current list item value.
19069     DeclRefExpr *Ref = nullptr;
19070     if (!VD)
19071       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19072     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19073     PrivateCopies.push_back(VDPrivateRefExpr);
19074     Inits.push_back(VDInitRefExpr);
19075 
19076     // We need to add a data sharing attribute for this variable to make sure it
19077     // is correctly captured. A variable that shows up in a use_device_ptr has
19078     // similar properties of a first private variable.
19079     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19080 
19081     // Create a mappable component for the list item. List items in this clause
19082     // only need a component.
19083     MVLI.VarBaseDeclarations.push_back(D);
19084     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19085     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
19086                                            /*IsNonContiguous=*/false);
19087   }
19088 
19089   if (MVLI.ProcessedVarList.empty())
19090     return nullptr;
19091 
19092   return OMPUseDevicePtrClause::Create(
19093       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
19094       MVLI.VarBaseDeclarations, MVLI.VarComponents);
19095 }
19096 
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)19097 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
19098                                                 const OMPVarListLocTy &Locs) {
19099   MappableVarListInfo MVLI(VarList);
19100 
19101   for (Expr *RefExpr : VarList) {
19102     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
19103     SourceLocation ELoc;
19104     SourceRange ERange;
19105     Expr *SimpleRefExpr = RefExpr;
19106     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19107                               /*AllowArraySection=*/true);
19108     if (Res.second) {
19109       // It will be analyzed later.
19110       MVLI.ProcessedVarList.push_back(RefExpr);
19111     }
19112     ValueDecl *D = Res.first;
19113     if (!D)
19114       continue;
19115     auto *VD = dyn_cast<VarDecl>(D);
19116 
19117     // If required, build a capture to implement the privatization initialized
19118     // with the current list item value.
19119     DeclRefExpr *Ref = nullptr;
19120     if (!VD)
19121       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19122     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
19123 
19124     // We need to add a data sharing attribute for this variable to make sure it
19125     // is correctly captured. A variable that shows up in a use_device_addr has
19126     // similar properties of a first private variable.
19127     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
19128 
19129     // Create a mappable component for the list item. List items in this clause
19130     // only need a component.
19131     MVLI.VarBaseDeclarations.push_back(D);
19132     MVLI.VarComponents.emplace_back();
19133     Expr *Component = SimpleRefExpr;
19134     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
19135                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
19136       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
19137     MVLI.VarComponents.back().emplace_back(Component, D,
19138                                            /*IsNonContiguous=*/false);
19139   }
19140 
19141   if (MVLI.ProcessedVarList.empty())
19142     return nullptr;
19143 
19144   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19145                                         MVLI.VarBaseDeclarations,
19146                                         MVLI.VarComponents);
19147 }
19148 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)19149 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
19150                                               const OMPVarListLocTy &Locs) {
19151   MappableVarListInfo MVLI(VarList);
19152   for (Expr *RefExpr : VarList) {
19153     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
19154     SourceLocation ELoc;
19155     SourceRange ERange;
19156     Expr *SimpleRefExpr = RefExpr;
19157     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19158     if (Res.second) {
19159       // It will be analyzed later.
19160       MVLI.ProcessedVarList.push_back(RefExpr);
19161     }
19162     ValueDecl *D = Res.first;
19163     if (!D)
19164       continue;
19165 
19166     QualType Type = D->getType();
19167     // item should be a pointer or array or reference to pointer or array
19168     if (!Type.getNonReferenceType()->isPointerType() &&
19169         !Type.getNonReferenceType()->isArrayType()) {
19170       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
19171           << 0 << RefExpr->getSourceRange();
19172       continue;
19173     }
19174 
19175     // Check if the declaration in the clause does not show up in any data
19176     // sharing attribute.
19177     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19178     if (isOpenMPPrivate(DVar.CKind)) {
19179       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19180           << getOpenMPClauseName(DVar.CKind)
19181           << getOpenMPClauseName(OMPC_is_device_ptr)
19182           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19183       reportOriginalDsa(*this, DSAStack, D, DVar);
19184       continue;
19185     }
19186 
19187     const Expr *ConflictExpr;
19188     if (DSAStack->checkMappableExprComponentListsForDecl(
19189             D, /*CurrentRegionOnly=*/true,
19190             [&ConflictExpr](
19191                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
19192                 OpenMPClauseKind) -> bool {
19193               ConflictExpr = R.front().getAssociatedExpression();
19194               return true;
19195             })) {
19196       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
19197       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
19198           << ConflictExpr->getSourceRange();
19199       continue;
19200     }
19201 
19202     // Store the components in the stack so that they can be used to check
19203     // against other clauses later on.
19204     OMPClauseMappableExprCommon::MappableComponent MC(
19205         SimpleRefExpr, D, /*IsNonContiguous=*/false);
19206     DSAStack->addMappableExpressionComponents(
19207         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
19208 
19209     // Record the expression we've just processed.
19210     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
19211 
19212     // Create a mappable component for the list item. List items in this clause
19213     // only need a component. We use a null declaration to signal fields in
19214     // 'this'.
19215     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
19216             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
19217            "Unexpected device pointer expression!");
19218     MVLI.VarBaseDeclarations.push_back(
19219         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19220     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19221     MVLI.VarComponents.back().push_back(MC);
19222   }
19223 
19224   if (MVLI.ProcessedVarList.empty())
19225     return nullptr;
19226 
19227   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19228                                       MVLI.VarBaseDeclarations,
19229                                       MVLI.VarComponents);
19230 }
19231 
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19232 OMPClause *Sema::ActOnOpenMPAllocateClause(
19233     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19234     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19235   if (Allocator) {
19236     // OpenMP [2.11.4 allocate Clause, Description]
19237     // allocator is an expression of omp_allocator_handle_t type.
19238     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
19239       return nullptr;
19240 
19241     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19242     if (AllocatorRes.isInvalid())
19243       return nullptr;
19244     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19245                                              DSAStack->getOMPAllocatorHandleT(),
19246                                              Sema::AA_Initializing,
19247                                              /*AllowExplicit=*/true);
19248     if (AllocatorRes.isInvalid())
19249       return nullptr;
19250     Allocator = AllocatorRes.get();
19251   } else {
19252     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19253     // allocate clauses that appear on a target construct or on constructs in a
19254     // target region must specify an allocator expression unless a requires
19255     // directive with the dynamic_allocators clause is present in the same
19256     // compilation unit.
19257     if (LangOpts.OpenMPIsDevice &&
19258         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19259       targetDiag(StartLoc, diag::err_expected_allocator_expression);
19260   }
19261   // Analyze and build list of variables.
19262   SmallVector<Expr *, 8> Vars;
19263   for (Expr *RefExpr : VarList) {
19264     assert(RefExpr && "NULL expr in OpenMP private clause.");
19265     SourceLocation ELoc;
19266     SourceRange ERange;
19267     Expr *SimpleRefExpr = RefExpr;
19268     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19269     if (Res.second) {
19270       // It will be analyzed later.
19271       Vars.push_back(RefExpr);
19272     }
19273     ValueDecl *D = Res.first;
19274     if (!D)
19275       continue;
19276 
19277     auto *VD = dyn_cast<VarDecl>(D);
19278     DeclRefExpr *Ref = nullptr;
19279     if (!VD && !CurContext->isDependentContext())
19280       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19281     Vars.push_back((VD || CurContext->isDependentContext())
19282                        ? RefExpr->IgnoreParens()
19283                        : Ref);
19284   }
19285 
19286   if (Vars.empty())
19287     return nullptr;
19288 
19289   if (Allocator)
19290     DSAStack->addInnerAllocatorExpr(Allocator);
19291   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19292                                    ColonLoc, EndLoc, Vars);
19293 }
19294 
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19295 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19296                                               SourceLocation StartLoc,
19297                                               SourceLocation LParenLoc,
19298                                               SourceLocation EndLoc) {
19299   SmallVector<Expr *, 8> Vars;
19300   for (Expr *RefExpr : VarList) {
19301     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19302     SourceLocation ELoc;
19303     SourceRange ERange;
19304     Expr *SimpleRefExpr = RefExpr;
19305     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19306     if (Res.second)
19307       // It will be analyzed later.
19308       Vars.push_back(RefExpr);
19309     ValueDecl *D = Res.first;
19310     if (!D)
19311       continue;
19312 
19313     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19314     // A list-item cannot appear in more than one nontemporal clause.
19315     if (const Expr *PrevRef =
19316             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
19317       Diag(ELoc, diag::err_omp_used_in_clause_twice)
19318           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19319       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19320           << getOpenMPClauseName(OMPC_nontemporal);
19321       continue;
19322     }
19323 
19324     Vars.push_back(RefExpr);
19325   }
19326 
19327   if (Vars.empty())
19328     return nullptr;
19329 
19330   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19331                                       Vars);
19332 }
19333 
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19334 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19335                                             SourceLocation StartLoc,
19336                                             SourceLocation LParenLoc,
19337                                             SourceLocation EndLoc) {
19338   SmallVector<Expr *, 8> Vars;
19339   for (Expr *RefExpr : VarList) {
19340     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19341     SourceLocation ELoc;
19342     SourceRange ERange;
19343     Expr *SimpleRefExpr = RefExpr;
19344     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19345                               /*AllowArraySection=*/true);
19346     if (Res.second)
19347       // It will be analyzed later.
19348       Vars.push_back(RefExpr);
19349     ValueDecl *D = Res.first;
19350     if (!D)
19351       continue;
19352 
19353     const DSAStackTy::DSAVarData DVar =
19354         DSAStack->getTopDSA(D, /*FromParent=*/true);
19355     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19356     // A list item that appears in the inclusive or exclusive clause must appear
19357     // in a reduction clause with the inscan modifier on the enclosing
19358     // worksharing-loop, worksharing-loop SIMD, or simd construct.
19359     if (DVar.CKind != OMPC_reduction ||
19360         DVar.Modifier != OMPC_REDUCTION_inscan)
19361       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19362           << RefExpr->getSourceRange();
19363 
19364     if (DSAStack->getParentDirective() != OMPD_unknown)
19365       DSAStack->markDeclAsUsedInScanDirective(D);
19366     Vars.push_back(RefExpr);
19367   }
19368 
19369   if (Vars.empty())
19370     return nullptr;
19371 
19372   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19373 }
19374 
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19375 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19376                                             SourceLocation StartLoc,
19377                                             SourceLocation LParenLoc,
19378                                             SourceLocation EndLoc) {
19379   SmallVector<Expr *, 8> Vars;
19380   for (Expr *RefExpr : VarList) {
19381     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19382     SourceLocation ELoc;
19383     SourceRange ERange;
19384     Expr *SimpleRefExpr = RefExpr;
19385     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19386                               /*AllowArraySection=*/true);
19387     if (Res.second)
19388       // It will be analyzed later.
19389       Vars.push_back(RefExpr);
19390     ValueDecl *D = Res.first;
19391     if (!D)
19392       continue;
19393 
19394     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
19395     DSAStackTy::DSAVarData DVar;
19396     if (ParentDirective != OMPD_unknown)
19397       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
19398     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19399     // A list item that appears in the inclusive or exclusive clause must appear
19400     // in a reduction clause with the inscan modifier on the enclosing
19401     // worksharing-loop, worksharing-loop SIMD, or simd construct.
19402     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19403         DVar.Modifier != OMPC_REDUCTION_inscan) {
19404       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19405           << RefExpr->getSourceRange();
19406     } else {
19407       DSAStack->markDeclAsUsedInScanDirective(D);
19408     }
19409     Vars.push_back(RefExpr);
19410   }
19411 
19412   if (Vars.empty())
19413     return nullptr;
19414 
19415   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19416 }
19417 
19418 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)19419 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19420   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19421   if (!OMPAlloctraitT.isNull())
19422     return true;
19423   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19424   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19425   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19426     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19427     return false;
19428   }
19429   Stack->setOMPAlloctraitT(PT.get());
19430   return true;
19431 }
19432 
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)19433 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19434     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19435     ArrayRef<UsesAllocatorsData> Data) {
19436   // OpenMP [2.12.5, target Construct]
19437   // allocator is an identifier of omp_allocator_handle_t type.
19438   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
19439     return nullptr;
19440   // OpenMP [2.12.5, target Construct]
19441   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19442   if (llvm::any_of(
19443           Data,
19444           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19445       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
19446     return nullptr;
19447   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19448   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19449     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19450     StringRef Allocator =
19451         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19452     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19453     PredefinedAllocators.insert(LookupSingleName(
19454         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19455   }
19456 
19457   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19458   for (const UsesAllocatorsData &D : Data) {
19459     Expr *AllocatorExpr = nullptr;
19460     // Check allocator expression.
19461     if (D.Allocator->isTypeDependent()) {
19462       AllocatorExpr = D.Allocator;
19463     } else {
19464       // Traits were specified - need to assign new allocator to the specified
19465       // allocator, so it must be an lvalue.
19466       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19467       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19468       bool IsPredefinedAllocator = false;
19469       if (DRE)
19470         IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19471       if (!DRE ||
19472           !(Context.hasSameUnqualifiedType(
19473                 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
19474             Context.typesAreCompatible(AllocatorExpr->getType(),
19475                                        DSAStack->getOMPAllocatorHandleT(),
19476                                        /*CompareUnqualified=*/true)) ||
19477           (!IsPredefinedAllocator &&
19478            (AllocatorExpr->getType().isConstant(Context) ||
19479             !AllocatorExpr->isLValue()))) {
19480         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19481             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19482             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19483         continue;
19484       }
19485       // OpenMP [2.12.5, target Construct]
19486       // Predefined allocators appearing in a uses_allocators clause cannot have
19487       // traits specified.
19488       if (IsPredefinedAllocator && D.AllocatorTraits) {
19489         Diag(D.AllocatorTraits->getExprLoc(),
19490              diag::err_omp_predefined_allocator_with_traits)
19491             << D.AllocatorTraits->getSourceRange();
19492         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19493             << cast<NamedDecl>(DRE->getDecl())->getName()
19494             << D.Allocator->getSourceRange();
19495         continue;
19496       }
19497       // OpenMP [2.12.5, target Construct]
19498       // Non-predefined allocators appearing in a uses_allocators clause must
19499       // have traits specified.
19500       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19501         Diag(D.Allocator->getExprLoc(),
19502              diag::err_omp_nonpredefined_allocator_without_traits);
19503         continue;
19504       }
19505       // No allocator traits - just convert it to rvalue.
19506       if (!D.AllocatorTraits)
19507         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19508       DSAStack->addUsesAllocatorsDecl(
19509           DRE->getDecl(),
19510           IsPredefinedAllocator
19511               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19512               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19513     }
19514     Expr *AllocatorTraitsExpr = nullptr;
19515     if (D.AllocatorTraits) {
19516       if (D.AllocatorTraits->isTypeDependent()) {
19517         AllocatorTraitsExpr = D.AllocatorTraits;
19518       } else {
19519         // OpenMP [2.12.5, target Construct]
19520         // Arrays that contain allocator traits that appear in a uses_allocators
19521         // clause must be constant arrays, have constant values and be defined
19522         // in the same scope as the construct in which the clause appears.
19523         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19524         // Check that traits expr is a constant array.
19525         QualType TraitTy;
19526         if (const ArrayType *Ty =
19527                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19528           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19529             TraitTy = ConstArrayTy->getElementType();
19530         if (TraitTy.isNull() ||
19531             !(Context.hasSameUnqualifiedType(TraitTy,
19532                                              DSAStack->getOMPAlloctraitT()) ||
19533               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
19534                                          /*CompareUnqualified=*/true))) {
19535           Diag(D.AllocatorTraits->getExprLoc(),
19536                diag::err_omp_expected_array_alloctraits)
19537               << AllocatorTraitsExpr->getType();
19538           continue;
19539         }
19540         // Do not map by default allocator traits if it is a standalone
19541         // variable.
19542         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19543           DSAStack->addUsesAllocatorsDecl(
19544               DRE->getDecl(),
19545               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19546       }
19547     }
19548     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19549     NewD.Allocator = AllocatorExpr;
19550     NewD.AllocatorTraits = AllocatorTraitsExpr;
19551     NewD.LParenLoc = D.LParenLoc;
19552     NewD.RParenLoc = D.RParenLoc;
19553   }
19554   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19555                                          NewData);
19556 }
19557 
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)19558 OMPClause *Sema::ActOnOpenMPAffinityClause(
19559     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19560     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19561   SmallVector<Expr *, 8> Vars;
19562   for (Expr *RefExpr : Locators) {
19563     assert(RefExpr && "NULL expr in OpenMP shared clause.");
19564     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19565       // It will be analyzed later.
19566       Vars.push_back(RefExpr);
19567       continue;
19568     }
19569 
19570     SourceLocation ELoc = RefExpr->getExprLoc();
19571     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19572 
19573     if (!SimpleExpr->isLValue()) {
19574       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19575           << 1 << 0 << RefExpr->getSourceRange();
19576       continue;
19577     }
19578 
19579     ExprResult Res;
19580     {
19581       Sema::TentativeAnalysisScope Trap(*this);
19582       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19583     }
19584     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19585         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19586       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19587           << 1 << 0 << RefExpr->getSourceRange();
19588       continue;
19589     }
19590     Vars.push_back(SimpleExpr);
19591   }
19592 
19593   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19594                                    EndLoc, Modifier, Vars);
19595 }
19596