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__anon850ef1bd0111::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__anon850ef1bd0111::DSAStackTy::ReductionData130     void set(BinaryOperatorKind BO, SourceRange RR) {
131       ReductionRange = RR;
132       ReductionOp = BO;
133     }
set__anon850ef1bd0111::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__anon850ef1bd0111::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__anon850ef1bd0111::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   /// Vector of declare variant construct traits.
314   SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
315 
316 public:
DSAStackTy(Sema & S)317   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
318 
319   /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)320   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
321   /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const322   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
323   /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)324   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
325   /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const326   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
327   /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)328   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
329                     Expr *Allocator) {
330     OMPPredefinedAllocators[AllocatorKind] = Allocator;
331   }
332   /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const333   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
334     return OMPPredefinedAllocators[AllocatorKind];
335   }
336   /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)337   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
338   /// Gets omp_depend_t type.
getOMPDependT() const339   QualType getOMPDependT() const { return OMPDependT; }
340 
341   /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)342   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
343   /// Gets omp_event_handle_t type.
getOMPEventHandleT() const344   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
345 
isClauseParsingMode() const346   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const347   OpenMPClauseKind getClauseParsingMode() const {
348     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
349     return ClauseKindMode;
350   }
setClauseParsingMode(OpenMPClauseKind K)351   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
352 
isBodyComplete() const353   bool isBodyComplete() const {
354     const SharingMapTy *Top = getTopOfStackOrNull();
355     return Top && Top->BodyComplete;
356   }
setBodyComplete()357   void setBodyComplete() {
358     getTopOfStack().BodyComplete = true;
359   }
360 
isForceVarCapturing() const361   bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)362   void setForceVarCapturing(bool V) { ForceCapturing = V; }
363 
setForceCaptureByReferenceInTargetExecutable(bool V)364   void setForceCaptureByReferenceInTargetExecutable(bool V) {
365     ForceCaptureByReferenceInTargetExecutable = V;
366   }
isForceCaptureByReferenceInTargetExecutable() const367   bool isForceCaptureByReferenceInTargetExecutable() const {
368     return ForceCaptureByReferenceInTargetExecutable;
369   }
370 
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)371   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
372             Scope *CurScope, SourceLocation Loc) {
373     assert(!IgnoredStackElements &&
374            "cannot change stack while ignoring elements");
375     if (Stack.empty() ||
376         Stack.back().second != CurrentNonCapturingFunctionScope)
377       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
378     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
379     Stack.back().first.back().DefaultAttrLoc = Loc;
380   }
381 
pop()382   void pop() {
383     assert(!IgnoredStackElements &&
384            "cannot change stack while ignoring elements");
385     assert(!Stack.back().first.empty() &&
386            "Data-sharing attributes stack is empty!");
387     Stack.back().first.pop_back();
388   }
389 
390   /// RAII object to temporarily leave the scope of a directive when we want to
391   /// logically operate in its parent.
392   class ParentDirectiveScope {
393     DSAStackTy &Self;
394     bool Active;
395   public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)396     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
397         : Self(Self), Active(false) {
398       if (Activate)
399         enable();
400     }
~ParentDirectiveScope()401     ~ParentDirectiveScope() { disable(); }
disable()402     void disable() {
403       if (Active) {
404         --Self.IgnoredStackElements;
405         Active = false;
406       }
407     }
enable()408     void enable() {
409       if (!Active) {
410         ++Self.IgnoredStackElements;
411         Active = true;
412       }
413     }
414   };
415 
416   /// Marks that we're started loop parsing.
loopInit()417   void loopInit() {
418     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
419            "Expected loop-based directive.");
420     getTopOfStack().LoopStart = true;
421   }
422   /// Start capturing of the variables in the loop context.
loopStart()423   void loopStart() {
424     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
425            "Expected loop-based directive.");
426     getTopOfStack().LoopStart = false;
427   }
428   /// true, if variables are captured, false otherwise.
isLoopStarted() const429   bool isLoopStarted() const {
430     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
431            "Expected loop-based directive.");
432     return !getTopOfStack().LoopStart;
433   }
434   /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)435   void resetPossibleLoopCounter(const Decl *D = nullptr) {
436     getTopOfStack().PossiblyLoopCounter =
437         D ? D->getCanonicalDecl() : D;
438   }
439   /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const440   const Decl *getPossiblyLoopCunter() const {
441     return getTopOfStack().PossiblyLoopCounter;
442   }
443   /// Start new OpenMP region stack in new non-capturing function.
pushFunction()444   void pushFunction() {
445     assert(!IgnoredStackElements &&
446            "cannot change stack while ignoring elements");
447     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
448     assert(!isa<CapturingScopeInfo>(CurFnScope));
449     CurrentNonCapturingFunctionScope = CurFnScope;
450   }
451   /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)452   void popFunction(const FunctionScopeInfo *OldFSI) {
453     assert(!IgnoredStackElements &&
454            "cannot change stack while ignoring elements");
455     if (!Stack.empty() && Stack.back().second == OldFSI) {
456       assert(Stack.back().first.empty());
457       Stack.pop_back();
458     }
459     CurrentNonCapturingFunctionScope = nullptr;
460     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
461       if (!isa<CapturingScopeInfo>(FSI)) {
462         CurrentNonCapturingFunctionScope = FSI;
463         break;
464       }
465     }
466   }
467 
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)468   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
469     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
470   }
471   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const472   getCriticalWithHint(const DeclarationNameInfo &Name) const {
473     auto I = Criticals.find(Name.getAsString());
474     if (I != Criticals.end())
475       return I->second;
476     return std::make_pair(nullptr, llvm::APSInt());
477   }
478   /// If 'aligned' declaration for given variable \a D was not seen yet,
479   /// add it and return NULL; otherwise return previous occurrence's expression
480   /// for diagnostics.
481   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
482   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
483   /// add it and return NULL; otherwise return previous occurrence's expression
484   /// for diagnostics.
485   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
486 
487   /// Register specified variable as loop control variable.
488   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
489   /// Check if the specified variable is a loop control variable for
490   /// current region.
491   /// \return The index of the loop control variable in the list of associated
492   /// for-loops (from outer to inner).
493   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
494   /// Check if the specified variable is a loop control variable for
495   /// parent region.
496   /// \return The index of the loop control variable in the list of associated
497   /// for-loops (from outer to inner).
498   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
499   /// Check if the specified variable is a loop control variable for
500   /// current region.
501   /// \return The index of the loop control variable in the list of associated
502   /// for-loops (from outer to inner).
503   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
504                                          unsigned Level) const;
505   /// Get the loop control variable for the I-th loop (or nullptr) in
506   /// parent directive.
507   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
508 
509   /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)510   void markDeclAsUsedInScanDirective(ValueDecl *D) {
511     if (SharingMapTy *Stack = getSecondOnStackOrNull())
512       Stack->UsedInScanDirective.insert(D);
513   }
514 
515   /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const516   bool isUsedInScanDirective(ValueDecl *D) const {
517     if (const SharingMapTy *Stack = getTopOfStackOrNull())
518       return Stack->UsedInScanDirective.count(D) > 0;
519     return false;
520   }
521 
522   /// Adds explicit data sharing attribute to the specified declaration.
523   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
524               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
525               bool AppliedToPointee = false);
526 
527   /// Adds additional information for the reduction items with the reduction id
528   /// represented as an operator.
529   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
530                                  BinaryOperatorKind BOK);
531   /// Adds additional information for the reduction items with the reduction id
532   /// represented as reduction identifier.
533   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
534                                  const Expr *ReductionRef);
535   /// Returns the location and reduction operation from the innermost parent
536   /// region for the given \p D.
537   const DSAVarData
538   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
539                                    BinaryOperatorKind &BOK,
540                                    Expr *&TaskgroupDescriptor) const;
541   /// Returns the location and reduction operation from the innermost parent
542   /// region for the given \p D.
543   const DSAVarData
544   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
545                                    const Expr *&ReductionRef,
546                                    Expr *&TaskgroupDescriptor) const;
547   /// Return reduction reference expression for the current taskgroup or
548   /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const549   Expr *getTaskgroupReductionRef() const {
550     assert((getTopOfStack().Directive == OMPD_taskgroup ||
551             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
552               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
553              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
554            "taskgroup reference expression requested for non taskgroup or "
555            "parallel/worksharing directive.");
556     return getTopOfStack().TaskgroupReductionRef;
557   }
558   /// Checks if the given \p VD declaration is actually a taskgroup reduction
559   /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const560   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
561     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
562            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
563                    ->getDecl() == VD;
564   }
565 
566   /// Returns data sharing attributes from top of the stack for the
567   /// specified declaration.
568   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
569   /// Returns data-sharing attributes for the specified declaration.
570   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
571   /// Returns data-sharing attributes for the specified declaration.
572   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
573   /// Checks if the specified variables has data-sharing attributes which
574   /// match specified \a CPred predicate in any directive which matches \a DPred
575   /// predicate.
576   const DSAVarData
577   hasDSA(ValueDecl *D,
578          const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
579          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
580          bool FromParent) const;
581   /// Checks if the specified variables has data-sharing attributes which
582   /// match specified \a CPred predicate in any innermost directive which
583   /// matches \a DPred predicate.
584   const DSAVarData
585   hasInnermostDSA(ValueDecl *D,
586                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
587                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
588                   bool FromParent) const;
589   /// Checks if the specified variables has explicit data-sharing
590   /// attributes which match specified \a CPred predicate at the specified
591   /// OpenMP region.
592   bool
593   hasExplicitDSA(const ValueDecl *D,
594                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
595                  unsigned Level, bool NotLastprivate = false) const;
596 
597   /// Returns true if the directive at level \Level matches in the
598   /// specified \a DPred predicate.
599   bool hasExplicitDirective(
600       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
601       unsigned Level) const;
602 
603   /// Finds a directive which matches specified \a DPred predicate.
604   bool hasDirective(
605       const llvm::function_ref<bool(
606           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
607           DPred,
608       bool FromParent) const;
609 
610   /// Returns currently analyzed directive.
getCurrentDirective() const611   OpenMPDirectiveKind getCurrentDirective() const {
612     const SharingMapTy *Top = getTopOfStackOrNull();
613     return Top ? Top->Directive : OMPD_unknown;
614   }
615   /// Returns directive kind at specified level.
getDirective(unsigned Level) const616   OpenMPDirectiveKind getDirective(unsigned Level) const {
617     assert(!isStackEmpty() && "No directive at specified level.");
618     return getStackElemAtLevel(Level).Directive;
619   }
620   /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const621   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
622                                        unsigned OpenMPCaptureLevel) const {
623     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
624     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
625     return CaptureRegions[OpenMPCaptureLevel];
626   }
627   /// Returns parent directive.
getParentDirective() const628   OpenMPDirectiveKind getParentDirective() const {
629     const SharingMapTy *Parent = getSecondOnStackOrNull();
630     return Parent ? Parent->Directive : OMPD_unknown;
631   }
632 
633   /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)634   void addRequiresDecl(OMPRequiresDecl *RD) {
635     RequiresDecls.push_back(RD);
636   }
637 
638   /// Checks if the defined 'requires' directive has specified type of clause.
639   template <typename ClauseType>
hasRequiresDeclWithClause() const640   bool hasRequiresDeclWithClause() const {
641     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
642       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
643         return isa<ClauseType>(C);
644       });
645     });
646   }
647 
648   /// Checks for a duplicate clause amongst previously declared requires
649   /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const650   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
651     bool IsDuplicate = false;
652     for (OMPClause *CNew : ClauseList) {
653       for (const OMPRequiresDecl *D : RequiresDecls) {
654         for (const OMPClause *CPrev : D->clauselists()) {
655           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
656             SemaRef.Diag(CNew->getBeginLoc(),
657                          diag::err_omp_requires_clause_redeclaration)
658                 << getOpenMPClauseName(CNew->getClauseKind());
659             SemaRef.Diag(CPrev->getBeginLoc(),
660                          diag::note_omp_requires_previous_clause)
661                 << getOpenMPClauseName(CPrev->getClauseKind());
662             IsDuplicate = true;
663           }
664         }
665       }
666     }
667     return IsDuplicate;
668   }
669 
670   /// Add location of previously encountered target to internal vector
addTargetDirLocation(SourceLocation LocStart)671   void addTargetDirLocation(SourceLocation LocStart) {
672     TargetLocations.push_back(LocStart);
673   }
674 
675   /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)676   void addAtomicDirectiveLoc(SourceLocation Loc) {
677     if (AtomicLocation.isInvalid())
678       AtomicLocation = Loc;
679   }
680 
681   /// Returns the location of the first encountered atomic directive in the
682   /// module.
getAtomicDirectiveLoc() const683   SourceLocation getAtomicDirectiveLoc() const {
684     return AtomicLocation;
685   }
686 
687   // Return previously encountered target region locations.
getEncounteredTargetLocs() const688   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
689     return TargetLocations;
690   }
691 
692   /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)693   void setDefaultDSANone(SourceLocation Loc) {
694     getTopOfStack().DefaultAttr = DSA_none;
695     getTopOfStack().DefaultAttrLoc = Loc;
696   }
697   /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)698   void setDefaultDSAShared(SourceLocation Loc) {
699     getTopOfStack().DefaultAttr = DSA_shared;
700     getTopOfStack().DefaultAttrLoc = Loc;
701   }
702   /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)703   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
704     getTopOfStack().DefaultAttr = DSA_firstprivate;
705     getTopOfStack().DefaultAttrLoc = Loc;
706   }
707   /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)708   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
709                          OpenMPDefaultmapClauseKind Kind,
710                          SourceLocation Loc) {
711     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
712     DMI.ImplicitBehavior = M;
713     DMI.SLoc = Loc;
714   }
715   /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)716   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
717     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
718       return getTopOfStack()
719                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
720                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
721              getTopOfStack()
722                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
723                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
724              getTopOfStack()
725                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
726                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
727     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
728            OMPC_DEFAULTMAP_MODIFIER_unknown;
729   }
730 
getConstructTraits()731   ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
732     return ConstructTraits;
733   }
handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,bool ScopeEntry)734   void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
735                             bool ScopeEntry) {
736     if (ScopeEntry)
737       ConstructTraits.append(Traits.begin(), Traits.end());
738     else
739       for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
740         llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
741         assert(Top == Trait && "Something left a trait on the stack!");
742         (void)Trait;
743         (void)Top;
744       }
745   }
746 
getDefaultDSA(unsigned Level) const747   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
748     return getStackSize() <= Level ? DSA_unspecified
749                                    : getStackElemAtLevel(Level).DefaultAttr;
750   }
getDefaultDSA() const751   DefaultDataSharingAttributes getDefaultDSA() const {
752     return isStackEmpty() ? DSA_unspecified
753                           : getTopOfStack().DefaultAttr;
754   }
getDefaultDSALocation() const755   SourceLocation getDefaultDSALocation() const {
756     return isStackEmpty() ? SourceLocation()
757                           : getTopOfStack().DefaultAttrLoc;
758   }
759   OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const760   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
761     return isStackEmpty()
762                ? OMPC_DEFAULTMAP_MODIFIER_unknown
763                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
764   }
765   OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const766   getDefaultmapModifierAtLevel(unsigned Level,
767                                OpenMPDefaultmapClauseKind Kind) const {
768     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
769   }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const770   bool isDefaultmapCapturedByRef(unsigned Level,
771                                  OpenMPDefaultmapClauseKind Kind) const {
772     OpenMPDefaultmapClauseModifier M =
773         getDefaultmapModifierAtLevel(Level, Kind);
774     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
775       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
776              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
777              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
778              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
779     }
780     return true;
781   }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)782   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
783                                      OpenMPDefaultmapClauseKind Kind) {
784     switch (Kind) {
785     case OMPC_DEFAULTMAP_scalar:
786     case OMPC_DEFAULTMAP_pointer:
787       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
788              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
789              (M == OMPC_DEFAULTMAP_MODIFIER_default);
790     case OMPC_DEFAULTMAP_aggregate:
791       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
792     default:
793       break;
794     }
795     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
796   }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const797   bool mustBeFirstprivateAtLevel(unsigned Level,
798                                  OpenMPDefaultmapClauseKind Kind) const {
799     OpenMPDefaultmapClauseModifier M =
800         getDefaultmapModifierAtLevel(Level, Kind);
801     return mustBeFirstprivateBase(M, Kind);
802   }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const803   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
804     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
805     return mustBeFirstprivateBase(M, Kind);
806   }
807 
808   /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)809   bool isThreadPrivate(VarDecl *D) {
810     const DSAVarData DVar = getTopDSA(D, false);
811     return isOpenMPThreadPrivate(DVar.CKind);
812   }
813 
814   /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)815   void setOrderedRegion(bool IsOrdered, const Expr *Param,
816                         OMPOrderedClause *Clause) {
817     if (IsOrdered)
818       getTopOfStack().OrderedRegion.emplace(Param, Clause);
819     else
820       getTopOfStack().OrderedRegion.reset();
821   }
822   /// Returns true, if region is ordered (has associated 'ordered' clause),
823   /// false - otherwise.
isOrderedRegion() const824   bool isOrderedRegion() const {
825     if (const SharingMapTy *Top = getTopOfStackOrNull())
826       return Top->OrderedRegion.hasValue();
827     return false;
828   }
829   /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const830   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
831     if (const SharingMapTy *Top = getTopOfStackOrNull())
832       if (Top->OrderedRegion.hasValue())
833         return Top->OrderedRegion.getValue();
834     return std::make_pair(nullptr, nullptr);
835   }
836   /// Returns true, if parent region is ordered (has associated
837   /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const838   bool isParentOrderedRegion() const {
839     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840       return Parent->OrderedRegion.hasValue();
841     return false;
842   }
843   /// Returns optional parameter for the ordered region.
844   std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const845   getParentOrderedRegionParam() const {
846     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
847       if (Parent->OrderedRegion.hasValue())
848         return Parent->OrderedRegion.getValue();
849     return std::make_pair(nullptr, nullptr);
850   }
851   /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)852   void setNowaitRegion(bool IsNowait = true) {
853     getTopOfStack().NowaitRegion = IsNowait;
854   }
855   /// Returns true, if parent region is nowait (has associated
856   /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const857   bool isParentNowaitRegion() const {
858     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
859       return Parent->NowaitRegion;
860     return false;
861   }
862   /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)863   void setParentCancelRegion(bool Cancel = true) {
864     if (SharingMapTy *Parent = getSecondOnStackOrNull())
865       Parent->CancelRegion |= Cancel;
866   }
867   /// Return true if current region has inner cancel construct.
isCancelRegion() const868   bool isCancelRegion() const {
869     const SharingMapTy *Top = getTopOfStackOrNull();
870     return Top ? Top->CancelRegion : false;
871   }
872 
873   /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)874   void setParentHasScanDirective(SourceLocation Loc) {
875     if (SharingMapTy *Parent = getSecondOnStackOrNull())
876       Parent->PrevScanLocation = Loc;
877   }
878   /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const879   bool doesParentHasScanDirective() const {
880     const SharingMapTy *Top = getSecondOnStackOrNull();
881     return Top ? Top->PrevScanLocation.isValid() : false;
882   }
883   /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const884   SourceLocation getParentScanDirectiveLoc() const {
885     const SharingMapTy *Top = getSecondOnStackOrNull();
886     return Top ? Top->PrevScanLocation : SourceLocation();
887   }
888   /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)889   void setParentHasOrderedDirective(SourceLocation Loc) {
890     if (SharingMapTy *Parent = getSecondOnStackOrNull())
891       Parent->PrevOrderedLocation = Loc;
892   }
893   /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const894   bool doesParentHasOrderedDirective() const {
895     const SharingMapTy *Top = getSecondOnStackOrNull();
896     return Top ? Top->PrevOrderedLocation.isValid() : false;
897   }
898   /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const899   SourceLocation getParentOrderedDirectiveLoc() const {
900     const SharingMapTy *Top = getSecondOnStackOrNull();
901     return Top ? Top->PrevOrderedLocation : SourceLocation();
902   }
903 
904   /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)905   void setAssociatedLoops(unsigned Val) {
906     getTopOfStack().AssociatedLoops = Val;
907     if (Val > 1)
908       getTopOfStack().HasMutipleLoops = true;
909   }
910   /// Return collapse value for region.
getAssociatedLoops() const911   unsigned getAssociatedLoops() const {
912     const SharingMapTy *Top = getTopOfStackOrNull();
913     return Top ? Top->AssociatedLoops : 0;
914   }
915   /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const916   bool hasMutipleLoops() const {
917     const SharingMapTy *Top = getTopOfStackOrNull();
918     return Top ? Top->HasMutipleLoops : false;
919   }
920 
921   /// Marks current target region as one with closely nested teams
922   /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)923   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
924     if (SharingMapTy *Parent = getSecondOnStackOrNull())
925       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
926   }
927   /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const928   bool hasInnerTeamsRegion() const {
929     return getInnerTeamsRegionLoc().isValid();
930   }
931   /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const932   SourceLocation getInnerTeamsRegionLoc() const {
933     const SharingMapTy *Top = getTopOfStackOrNull();
934     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
935   }
936 
getCurScope() const937   Scope *getCurScope() const {
938     const SharingMapTy *Top = getTopOfStackOrNull();
939     return Top ? Top->CurScope : nullptr;
940   }
setContext(DeclContext * DC)941   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const942   SourceLocation getConstructLoc() const {
943     const SharingMapTy *Top = getTopOfStackOrNull();
944     return Top ? Top->ConstructLoc : SourceLocation();
945   }
946 
947   /// Do the check specified in \a Check to all component lists and return true
948   /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const949   bool checkMappableExprComponentListsForDecl(
950       const ValueDecl *VD, bool CurrentRegionOnly,
951       const llvm::function_ref<
952           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
953                OpenMPClauseKind)>
954           Check) const {
955     if (isStackEmpty())
956       return false;
957     auto SI = begin();
958     auto SE = end();
959 
960     if (SI == SE)
961       return false;
962 
963     if (CurrentRegionOnly)
964       SE = std::next(SI);
965     else
966       std::advance(SI, 1);
967 
968     for (; SI != SE; ++SI) {
969       auto MI = SI->MappedExprComponents.find(VD);
970       if (MI != SI->MappedExprComponents.end())
971         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
972              MI->second.Components)
973           if (Check(L, MI->second.Kind))
974             return true;
975     }
976     return false;
977   }
978 
979   /// Do the check specified in \a Check to all component lists at a given level
980   /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const981   bool checkMappableExprComponentListsForDeclAtLevel(
982       const ValueDecl *VD, unsigned Level,
983       const llvm::function_ref<
984           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
985                OpenMPClauseKind)>
986           Check) const {
987     if (getStackSize() <= Level)
988       return false;
989 
990     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
991     auto MI = StackElem.MappedExprComponents.find(VD);
992     if (MI != StackElem.MappedExprComponents.end())
993       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
994            MI->second.Components)
995         if (Check(L, MI->second.Kind))
996           return true;
997     return false;
998   }
999 
1000   /// Create a new mappable expression component list associated with a given
1001   /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)1002   void addMappableExpressionComponents(
1003       const ValueDecl *VD,
1004       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1005       OpenMPClauseKind WhereFoundClauseKind) {
1006     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1007     // Create new entry and append the new components there.
1008     MEC.Components.resize(MEC.Components.size() + 1);
1009     MEC.Components.back().append(Components.begin(), Components.end());
1010     MEC.Kind = WhereFoundClauseKind;
1011   }
1012 
getNestingLevel() const1013   unsigned getNestingLevel() const {
1014     assert(!isStackEmpty());
1015     return getStackSize() - 1;
1016   }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)1017   void addDoacrossDependClause(OMPDependClause *C,
1018                                const OperatorOffsetTy &OpsOffs) {
1019     SharingMapTy *Parent = getSecondOnStackOrNull();
1020     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1021     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1022   }
1023   llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const1024   getDoacrossDependClauses() const {
1025     const SharingMapTy &StackElem = getTopOfStack();
1026     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1027       const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1028       return llvm::make_range(Ref.begin(), Ref.end());
1029     }
1030     return llvm::make_range(StackElem.DoacrossDepends.end(),
1031                             StackElem.DoacrossDepends.end());
1032   }
1033 
1034   // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1035   void addMappedClassesQualTypes(QualType QT) {
1036     SharingMapTy &StackElem = getTopOfStack();
1037     StackElem.MappedClassesQualTypes.insert(QT);
1038   }
1039 
1040   // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1041   bool isClassPreviouslyMapped(QualType QT) const {
1042     const SharingMapTy &StackElem = getTopOfStack();
1043     return StackElem.MappedClassesQualTypes.count(QT) != 0;
1044   }
1045 
1046   /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1047   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1048     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1049                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1050            "Expected declare target link global.");
1051     for (auto &Elem : *this) {
1052       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1053         Elem.DeclareTargetLinkVarDecls.push_back(E);
1054         return;
1055       }
1056     }
1057   }
1058 
1059   /// Returns the list of globals with declare target link if current directive
1060   /// is target.
getLinkGlobals() const1061   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1062     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1063            "Expected target executable directive.");
1064     return getTopOfStack().DeclareTargetLinkVarDecls;
1065   }
1066 
1067   /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1068   void addInnerAllocatorExpr(Expr *E) {
1069     getTopOfStack().InnerUsedAllocators.push_back(E);
1070   }
1071   /// Return list of used allocators.
getInnerAllocators() const1072   ArrayRef<Expr *> getInnerAllocators() const {
1073     return getTopOfStack().InnerUsedAllocators;
1074   }
1075   /// Marks the declaration as implicitly firstprivate nin the task-based
1076   /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1077   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1078     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1079   }
1080   /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1081   bool isImplicitTaskFirstprivate(Decl *D) const {
1082     return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1083   }
1084 
1085   /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1086   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1087     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1088   }
1089   /// Checks if specified decl is used in uses allocator clause as the
1090   /// allocator.
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1091   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1092                                                         const Decl *D) const {
1093     const SharingMapTy &StackElem = getTopOfStack();
1094     auto I = StackElem.UsesAllocatorsDecls.find(D);
1095     if (I == StackElem.UsesAllocatorsDecls.end())
1096       return None;
1097     return I->getSecond();
1098   }
isUsesAllocatorsDecl(const Decl * D) const1099   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1100     const SharingMapTy &StackElem = getTopOfStack();
1101     auto I = StackElem.UsesAllocatorsDecls.find(D);
1102     if (I == StackElem.UsesAllocatorsDecls.end())
1103       return None;
1104     return I->getSecond();
1105   }
1106 
addDeclareMapperVarRef(Expr * Ref)1107   void addDeclareMapperVarRef(Expr *Ref) {
1108     SharingMapTy &StackElem = getTopOfStack();
1109     StackElem.DeclareMapperVar = Ref;
1110   }
getDeclareMapperVarRef() const1111   const Expr *getDeclareMapperVarRef() const {
1112     const SharingMapTy *Top = getTopOfStackOrNull();
1113     return Top ? Top->DeclareMapperVar : nullptr;
1114   }
1115 };
1116 
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1117 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1118   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1119 }
1120 
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1121 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1122   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1123          DKind == OMPD_unknown;
1124 }
1125 
1126 } // namespace
1127 
getExprAsWritten(const Expr * E)1128 static const Expr *getExprAsWritten(const Expr *E) {
1129   if (const auto *FE = dyn_cast<FullExpr>(E))
1130     E = FE->getSubExpr();
1131 
1132   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1133     E = MTE->getSubExpr();
1134 
1135   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1136     E = Binder->getSubExpr();
1137 
1138   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1139     E = ICE->getSubExprAsWritten();
1140   return E->IgnoreParens();
1141 }
1142 
getExprAsWritten(Expr * E)1143 static Expr *getExprAsWritten(Expr *E) {
1144   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1145 }
1146 
getCanonicalDecl(const ValueDecl * D)1147 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1148   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1149     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1150       D = ME->getMemberDecl();
1151   const auto *VD = dyn_cast<VarDecl>(D);
1152   const auto *FD = dyn_cast<FieldDecl>(D);
1153   if (VD != nullptr) {
1154     VD = VD->getCanonicalDecl();
1155     D = VD;
1156   } else {
1157     assert(FD);
1158     FD = FD->getCanonicalDecl();
1159     D = FD;
1160   }
1161   return D;
1162 }
1163 
getCanonicalDecl(ValueDecl * D)1164 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1165   return const_cast<ValueDecl *>(
1166       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1167 }
1168 
getDSA(const_iterator & Iter,ValueDecl * D) const1169 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1170                                           ValueDecl *D) const {
1171   D = getCanonicalDecl(D);
1172   auto *VD = dyn_cast<VarDecl>(D);
1173   const auto *FD = dyn_cast<FieldDecl>(D);
1174   DSAVarData DVar;
1175   if (Iter == end()) {
1176     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1177     // in a region but not in construct]
1178     //  File-scope or namespace-scope variables referenced in called routines
1179     //  in the region are shared unless they appear in a threadprivate
1180     //  directive.
1181     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1182       DVar.CKind = OMPC_shared;
1183 
1184     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1185     // in a region but not in construct]
1186     //  Variables with static storage duration that are declared in called
1187     //  routines in the region are shared.
1188     if (VD && VD->hasGlobalStorage())
1189       DVar.CKind = OMPC_shared;
1190 
1191     // Non-static data members are shared by default.
1192     if (FD)
1193       DVar.CKind = OMPC_shared;
1194 
1195     return DVar;
1196   }
1197 
1198   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1199   // in a Construct, C/C++, predetermined, p.1]
1200   // Variables with automatic storage duration that are declared in a scope
1201   // inside the construct are private.
1202   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1203       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1204     DVar.CKind = OMPC_private;
1205     return DVar;
1206   }
1207 
1208   DVar.DKind = Iter->Directive;
1209   // Explicitly specified attributes and local variables with predetermined
1210   // attributes.
1211   if (Iter->SharingMap.count(D)) {
1212     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1213     DVar.RefExpr = Data.RefExpr.getPointer();
1214     DVar.PrivateCopy = Data.PrivateCopy;
1215     DVar.CKind = Data.Attributes;
1216     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1217     DVar.Modifier = Data.Modifier;
1218     DVar.AppliedToPointee = Data.AppliedToPointee;
1219     return DVar;
1220   }
1221 
1222   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1223   // in a Construct, C/C++, implicitly determined, p.1]
1224   //  In a parallel or task construct, the data-sharing attributes of these
1225   //  variables are determined by the default clause, if present.
1226   switch (Iter->DefaultAttr) {
1227   case DSA_shared:
1228     DVar.CKind = OMPC_shared;
1229     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1230     return DVar;
1231   case DSA_none:
1232     return DVar;
1233   case DSA_firstprivate:
1234     if (VD->getStorageDuration() == SD_Static &&
1235         VD->getDeclContext()->isFileContext()) {
1236       DVar.CKind = OMPC_unknown;
1237     } else {
1238       DVar.CKind = OMPC_firstprivate;
1239     }
1240     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1241     return DVar;
1242   case DSA_unspecified:
1243     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1244     // in a Construct, implicitly determined, p.2]
1245     //  In a parallel construct, if no default clause is present, these
1246     //  variables are shared.
1247     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1248     if ((isOpenMPParallelDirective(DVar.DKind) &&
1249          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1250         isOpenMPTeamsDirective(DVar.DKind)) {
1251       DVar.CKind = OMPC_shared;
1252       return DVar;
1253     }
1254 
1255     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1256     // in a Construct, implicitly determined, p.4]
1257     //  In a task construct, if no default clause is present, a variable that in
1258     //  the enclosing context is determined to be shared by all implicit tasks
1259     //  bound to the current team is shared.
1260     if (isOpenMPTaskingDirective(DVar.DKind)) {
1261       DSAVarData DVarTemp;
1262       const_iterator I = Iter, E = end();
1263       do {
1264         ++I;
1265         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1266         // Referenced in a Construct, implicitly determined, p.6]
1267         //  In a task construct, if no default clause is present, a variable
1268         //  whose data-sharing attribute is not determined by the rules above is
1269         //  firstprivate.
1270         DVarTemp = getDSA(I, D);
1271         if (DVarTemp.CKind != OMPC_shared) {
1272           DVar.RefExpr = nullptr;
1273           DVar.CKind = OMPC_firstprivate;
1274           return DVar;
1275         }
1276       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1277       DVar.CKind =
1278           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1279       return DVar;
1280     }
1281   }
1282   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1283   // in a Construct, implicitly determined, p.3]
1284   //  For constructs other than task, if no default clause is present, these
1285   //  variables inherit their data-sharing attributes from the enclosing
1286   //  context.
1287   return getDSA(++Iter, D);
1288 }
1289 
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1290 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1291                                          const Expr *NewDE) {
1292   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1293   D = getCanonicalDecl(D);
1294   SharingMapTy &StackElem = getTopOfStack();
1295   auto It = StackElem.AlignedMap.find(D);
1296   if (It == StackElem.AlignedMap.end()) {
1297     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1298     StackElem.AlignedMap[D] = NewDE;
1299     return nullptr;
1300   }
1301   assert(It->second && "Unexpected nullptr expr in the aligned map");
1302   return It->second;
1303 }
1304 
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1305 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1306                                              const Expr *NewDE) {
1307   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1308   D = getCanonicalDecl(D);
1309   SharingMapTy &StackElem = getTopOfStack();
1310   auto It = StackElem.NontemporalMap.find(D);
1311   if (It == StackElem.NontemporalMap.end()) {
1312     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1313     StackElem.NontemporalMap[D] = NewDE;
1314     return nullptr;
1315   }
1316   assert(It->second && "Unexpected nullptr expr in the aligned map");
1317   return It->second;
1318 }
1319 
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1320 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1321   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1322   D = getCanonicalDecl(D);
1323   SharingMapTy &StackElem = getTopOfStack();
1324   StackElem.LCVMap.try_emplace(
1325       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1326 }
1327 
1328 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1329 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1330   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1331   D = getCanonicalDecl(D);
1332   const SharingMapTy &StackElem = getTopOfStack();
1333   auto It = StackElem.LCVMap.find(D);
1334   if (It != StackElem.LCVMap.end())
1335     return It->second;
1336   return {0, nullptr};
1337 }
1338 
1339 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1340 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1341   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1342   D = getCanonicalDecl(D);
1343   for (unsigned I = Level + 1; I > 0; --I) {
1344     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1345     auto It = StackElem.LCVMap.find(D);
1346     if (It != StackElem.LCVMap.end())
1347       return It->second;
1348   }
1349   return {0, nullptr};
1350 }
1351 
1352 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1353 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1354   const SharingMapTy *Parent = getSecondOnStackOrNull();
1355   assert(Parent && "Data-sharing attributes stack is empty");
1356   D = getCanonicalDecl(D);
1357   auto It = Parent->LCVMap.find(D);
1358   if (It != Parent->LCVMap.end())
1359     return It->second;
1360   return {0, nullptr};
1361 }
1362 
getParentLoopControlVariable(unsigned I) const1363 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1364   const SharingMapTy *Parent = getSecondOnStackOrNull();
1365   assert(Parent && "Data-sharing attributes stack is empty");
1366   if (Parent->LCVMap.size() < I)
1367     return nullptr;
1368   for (const auto &Pair : Parent->LCVMap)
1369     if (Pair.second.first == I)
1370       return Pair.first;
1371   return nullptr;
1372 }
1373 
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1374 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1375                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1376                         bool AppliedToPointee) {
1377   D = getCanonicalDecl(D);
1378   if (A == OMPC_threadprivate) {
1379     DSAInfo &Data = Threadprivates[D];
1380     Data.Attributes = A;
1381     Data.RefExpr.setPointer(E);
1382     Data.PrivateCopy = nullptr;
1383     Data.Modifier = Modifier;
1384   } else {
1385     DSAInfo &Data = getTopOfStack().SharingMap[D];
1386     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1387            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1388            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1389            (isLoopControlVariable(D).first && A == OMPC_private));
1390     Data.Modifier = Modifier;
1391     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1392       Data.RefExpr.setInt(/*IntVal=*/true);
1393       return;
1394     }
1395     const bool IsLastprivate =
1396         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1397     Data.Attributes = A;
1398     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1399     Data.PrivateCopy = PrivateCopy;
1400     Data.AppliedToPointee = AppliedToPointee;
1401     if (PrivateCopy) {
1402       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1403       Data.Modifier = Modifier;
1404       Data.Attributes = A;
1405       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1406       Data.PrivateCopy = nullptr;
1407       Data.AppliedToPointee = AppliedToPointee;
1408     }
1409   }
1410 }
1411 
1412 /// 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)1413 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1414                              StringRef Name, const AttrVec *Attrs = nullptr,
1415                              DeclRefExpr *OrigRef = nullptr) {
1416   DeclContext *DC = SemaRef.CurContext;
1417   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1418   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1419   auto *Decl =
1420       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1421   if (Attrs) {
1422     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1423          I != E; ++I)
1424       Decl->addAttr(*I);
1425   }
1426   Decl->setImplicit();
1427   if (OrigRef) {
1428     Decl->addAttr(
1429         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1430   }
1431   return Decl;
1432 }
1433 
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1434 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1435                                      SourceLocation Loc,
1436                                      bool RefersToCapture = false) {
1437   D->setReferenced();
1438   D->markUsed(S.Context);
1439   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1440                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1441                              VK_LValue);
1442 }
1443 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1444 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1445                                            BinaryOperatorKind BOK) {
1446   D = getCanonicalDecl(D);
1447   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1448   assert(
1449       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1450       "Additional reduction info may be specified only for reduction items.");
1451   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1452   assert(ReductionData.ReductionRange.isInvalid() &&
1453          (getTopOfStack().Directive == OMPD_taskgroup ||
1454           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1455             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1456            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1457          "Additional reduction info may be specified only once for reduction "
1458          "items.");
1459   ReductionData.set(BOK, SR);
1460   Expr *&TaskgroupReductionRef =
1461       getTopOfStack().TaskgroupReductionRef;
1462   if (!TaskgroupReductionRef) {
1463     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1464                                SemaRef.Context.VoidPtrTy, ".task_red.");
1465     TaskgroupReductionRef =
1466         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1467   }
1468 }
1469 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1470 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1471                                            const Expr *ReductionRef) {
1472   D = getCanonicalDecl(D);
1473   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1474   assert(
1475       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1476       "Additional reduction info may be specified only for reduction items.");
1477   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1478   assert(ReductionData.ReductionRange.isInvalid() &&
1479          (getTopOfStack().Directive == OMPD_taskgroup ||
1480           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1481             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1482            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1483          "Additional reduction info may be specified only once for reduction "
1484          "items.");
1485   ReductionData.set(ReductionRef, SR);
1486   Expr *&TaskgroupReductionRef =
1487       getTopOfStack().TaskgroupReductionRef;
1488   if (!TaskgroupReductionRef) {
1489     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1490                                SemaRef.Context.VoidPtrTy, ".task_red.");
1491     TaskgroupReductionRef =
1492         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1493   }
1494 }
1495 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1496 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1497     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1498     Expr *&TaskgroupDescriptor) const {
1499   D = getCanonicalDecl(D);
1500   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1501   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1502     const DSAInfo &Data = I->SharingMap.lookup(D);
1503     if (Data.Attributes != OMPC_reduction ||
1504         Data.Modifier != OMPC_REDUCTION_task)
1505       continue;
1506     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1507     if (!ReductionData.ReductionOp ||
1508         ReductionData.ReductionOp.is<const Expr *>())
1509       return DSAVarData();
1510     SR = ReductionData.ReductionRange;
1511     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1512     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1513                                        "expression for the descriptor is not "
1514                                        "set.");
1515     TaskgroupDescriptor = I->TaskgroupReductionRef;
1516     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1517                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1518                       /*AppliedToPointee=*/false);
1519   }
1520   return DSAVarData();
1521 }
1522 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1523 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1524     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1525     Expr *&TaskgroupDescriptor) const {
1526   D = getCanonicalDecl(D);
1527   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1528   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1529     const DSAInfo &Data = I->SharingMap.lookup(D);
1530     if (Data.Attributes != OMPC_reduction ||
1531         Data.Modifier != OMPC_REDUCTION_task)
1532       continue;
1533     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1534     if (!ReductionData.ReductionOp ||
1535         !ReductionData.ReductionOp.is<const Expr *>())
1536       return DSAVarData();
1537     SR = ReductionData.ReductionRange;
1538     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1539     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1540                                        "expression for the descriptor is not "
1541                                        "set.");
1542     TaskgroupDescriptor = I->TaskgroupReductionRef;
1543     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1544                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1545                       /*AppliedToPointee=*/false);
1546   }
1547   return DSAVarData();
1548 }
1549 
isOpenMPLocal(VarDecl * D,const_iterator I) const1550 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1551   D = D->getCanonicalDecl();
1552   for (const_iterator E = end(); I != E; ++I) {
1553     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1554         isOpenMPTargetExecutionDirective(I->Directive)) {
1555       if (I->CurScope) {
1556         Scope *TopScope = I->CurScope->getParent();
1557         Scope *CurScope = getCurScope();
1558         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1559           CurScope = CurScope->getParent();
1560         return CurScope != TopScope;
1561       }
1562       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1563         if (I->Context == DC)
1564           return true;
1565       return false;
1566     }
1567   }
1568   return false;
1569 }
1570 
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1571 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1572                                   bool AcceptIfMutable = true,
1573                                   bool *IsClassType = nullptr) {
1574   ASTContext &Context = SemaRef.getASTContext();
1575   Type = Type.getNonReferenceType().getCanonicalType();
1576   bool IsConstant = Type.isConstant(Context);
1577   Type = Context.getBaseElementType(Type);
1578   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1579                                 ? Type->getAsCXXRecordDecl()
1580                                 : nullptr;
1581   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1582     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1583       RD = CTD->getTemplatedDecl();
1584   if (IsClassType)
1585     *IsClassType = RD;
1586   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1587                          RD->hasDefinition() && RD->hasMutableFields());
1588 }
1589 
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1590 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1591                                       QualType Type, OpenMPClauseKind CKind,
1592                                       SourceLocation ELoc,
1593                                       bool AcceptIfMutable = true,
1594                                       bool ListItemNotVar = false) {
1595   ASTContext &Context = SemaRef.getASTContext();
1596   bool IsClassType;
1597   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1598     unsigned Diag = ListItemNotVar
1599                         ? diag::err_omp_const_list_item
1600                         : IsClassType ? diag::err_omp_const_not_mutable_variable
1601                                       : diag::err_omp_const_variable;
1602     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1603     if (!ListItemNotVar && D) {
1604       const VarDecl *VD = dyn_cast<VarDecl>(D);
1605       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1606                                VarDecl::DeclarationOnly;
1607       SemaRef.Diag(D->getLocation(),
1608                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1609           << D;
1610     }
1611     return true;
1612   }
1613   return false;
1614 }
1615 
getTopDSA(ValueDecl * D,bool FromParent)1616 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1617                                                    bool FromParent) {
1618   D = getCanonicalDecl(D);
1619   DSAVarData DVar;
1620 
1621   auto *VD = dyn_cast<VarDecl>(D);
1622   auto TI = Threadprivates.find(D);
1623   if (TI != Threadprivates.end()) {
1624     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1625     DVar.CKind = OMPC_threadprivate;
1626     DVar.Modifier = TI->getSecond().Modifier;
1627     return DVar;
1628   }
1629   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1630     DVar.RefExpr = buildDeclRefExpr(
1631         SemaRef, VD, D->getType().getNonReferenceType(),
1632         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1633     DVar.CKind = OMPC_threadprivate;
1634     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1635     return DVar;
1636   }
1637   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1638   // in a Construct, C/C++, predetermined, p.1]
1639   //  Variables appearing in threadprivate directives are threadprivate.
1640   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1641        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1642          SemaRef.getLangOpts().OpenMPUseTLS &&
1643          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1644       (VD && VD->getStorageClass() == SC_Register &&
1645        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1646     DVar.RefExpr = buildDeclRefExpr(
1647         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1648     DVar.CKind = OMPC_threadprivate;
1649     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1650     return DVar;
1651   }
1652   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1653       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1654       !isLoopControlVariable(D).first) {
1655     const_iterator IterTarget =
1656         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1657           return isOpenMPTargetExecutionDirective(Data.Directive);
1658         });
1659     if (IterTarget != end()) {
1660       const_iterator ParentIterTarget = IterTarget + 1;
1661       for (const_iterator Iter = begin();
1662            Iter != ParentIterTarget; ++Iter) {
1663         if (isOpenMPLocal(VD, Iter)) {
1664           DVar.RefExpr =
1665               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1666                                D->getLocation());
1667           DVar.CKind = OMPC_threadprivate;
1668           return DVar;
1669         }
1670       }
1671       if (!isClauseParsingMode() || IterTarget != begin()) {
1672         auto DSAIter = IterTarget->SharingMap.find(D);
1673         if (DSAIter != IterTarget->SharingMap.end() &&
1674             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1675           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1676           DVar.CKind = OMPC_threadprivate;
1677           return DVar;
1678         }
1679         const_iterator End = end();
1680         if (!SemaRef.isOpenMPCapturedByRef(
1681                 D, std::distance(ParentIterTarget, End),
1682                 /*OpenMPCaptureLevel=*/0)) {
1683           DVar.RefExpr =
1684               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1685                                IterTarget->ConstructLoc);
1686           DVar.CKind = OMPC_threadprivate;
1687           return DVar;
1688         }
1689       }
1690     }
1691   }
1692 
1693   if (isStackEmpty())
1694     // Not in OpenMP execution region and top scope was already checked.
1695     return DVar;
1696 
1697   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1698   // in a Construct, C/C++, predetermined, p.4]
1699   //  Static data members are shared.
1700   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1701   // in a Construct, C/C++, predetermined, p.7]
1702   //  Variables with static storage duration that are declared in a scope
1703   //  inside the construct are shared.
1704   if (VD && VD->isStaticDataMember()) {
1705     // Check for explicitly specified attributes.
1706     const_iterator I = begin();
1707     const_iterator EndI = end();
1708     if (FromParent && I != EndI)
1709       ++I;
1710     if (I != EndI) {
1711       auto It = I->SharingMap.find(D);
1712       if (It != I->SharingMap.end()) {
1713         const DSAInfo &Data = It->getSecond();
1714         DVar.RefExpr = Data.RefExpr.getPointer();
1715         DVar.PrivateCopy = Data.PrivateCopy;
1716         DVar.CKind = Data.Attributes;
1717         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1718         DVar.DKind = I->Directive;
1719         DVar.Modifier = Data.Modifier;
1720         DVar.AppliedToPointee = Data.AppliedToPointee;
1721         return DVar;
1722       }
1723     }
1724 
1725     DVar.CKind = OMPC_shared;
1726     return DVar;
1727   }
1728 
1729   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1730   // The predetermined shared attribute for const-qualified types having no
1731   // mutable members was removed after OpenMP 3.1.
1732   if (SemaRef.LangOpts.OpenMP <= 31) {
1733     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1734     // in a Construct, C/C++, predetermined, p.6]
1735     //  Variables with const qualified type having no mutable member are
1736     //  shared.
1737     if (isConstNotMutableType(SemaRef, D->getType())) {
1738       // Variables with const-qualified type having no mutable member may be
1739       // listed in a firstprivate clause, even if they are static data members.
1740       DSAVarData DVarTemp = hasInnermostDSA(
1741           D,
1742           [](OpenMPClauseKind C, bool) {
1743             return C == OMPC_firstprivate || C == OMPC_shared;
1744           },
1745           MatchesAlways, FromParent);
1746       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1747         return DVarTemp;
1748 
1749       DVar.CKind = OMPC_shared;
1750       return DVar;
1751     }
1752   }
1753 
1754   // Explicitly specified attributes and local variables with predetermined
1755   // attributes.
1756   const_iterator I = begin();
1757   const_iterator EndI = end();
1758   if (FromParent && I != EndI)
1759     ++I;
1760   if (I == EndI)
1761     return DVar;
1762   auto It = I->SharingMap.find(D);
1763   if (It != I->SharingMap.end()) {
1764     const DSAInfo &Data = It->getSecond();
1765     DVar.RefExpr = Data.RefExpr.getPointer();
1766     DVar.PrivateCopy = Data.PrivateCopy;
1767     DVar.CKind = Data.Attributes;
1768     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1769     DVar.DKind = I->Directive;
1770     DVar.Modifier = Data.Modifier;
1771     DVar.AppliedToPointee = Data.AppliedToPointee;
1772   }
1773 
1774   return DVar;
1775 }
1776 
getImplicitDSA(ValueDecl * D,bool FromParent) const1777 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1778                                                         bool FromParent) const {
1779   if (isStackEmpty()) {
1780     const_iterator I;
1781     return getDSA(I, D);
1782   }
1783   D = getCanonicalDecl(D);
1784   const_iterator StartI = begin();
1785   const_iterator EndI = end();
1786   if (FromParent && StartI != EndI)
1787     ++StartI;
1788   return getDSA(StartI, D);
1789 }
1790 
getImplicitDSA(ValueDecl * D,unsigned Level) const1791 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1792                                                         unsigned Level) const {
1793   if (getStackSize() <= Level)
1794     return DSAVarData();
1795   D = getCanonicalDecl(D);
1796   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1797   return getDSA(StartI, D);
1798 }
1799 
1800 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1801 DSAStackTy::hasDSA(ValueDecl *D,
1802                    const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1803                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1804                    bool FromParent) const {
1805   if (isStackEmpty())
1806     return {};
1807   D = getCanonicalDecl(D);
1808   const_iterator I = begin();
1809   const_iterator EndI = end();
1810   if (FromParent && I != EndI)
1811     ++I;
1812   for (; I != EndI; ++I) {
1813     if (!DPred(I->Directive) &&
1814         !isImplicitOrExplicitTaskingRegion(I->Directive))
1815       continue;
1816     const_iterator NewI = I;
1817     DSAVarData DVar = getDSA(NewI, D);
1818     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1819       return DVar;
1820   }
1821   return {};
1822 }
1823 
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1824 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1825     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1826     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1827     bool FromParent) const {
1828   if (isStackEmpty())
1829     return {};
1830   D = getCanonicalDecl(D);
1831   const_iterator StartI = begin();
1832   const_iterator EndI = end();
1833   if (FromParent && StartI != EndI)
1834     ++StartI;
1835   if (StartI == EndI || !DPred(StartI->Directive))
1836     return {};
1837   const_iterator NewI = StartI;
1838   DSAVarData DVar = getDSA(NewI, D);
1839   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1840              ? DVar
1841              : DSAVarData();
1842 }
1843 
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1844 bool DSAStackTy::hasExplicitDSA(
1845     const ValueDecl *D,
1846     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1847     unsigned Level, bool NotLastprivate) const {
1848   if (getStackSize() <= Level)
1849     return false;
1850   D = getCanonicalDecl(D);
1851   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1852   auto I = StackElem.SharingMap.find(D);
1853   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1854       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1855       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1856     return true;
1857   // Check predetermined rules for the loop control variables.
1858   auto LI = StackElem.LCVMap.find(D);
1859   if (LI != StackElem.LCVMap.end())
1860     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1861   return false;
1862 }
1863 
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1864 bool DSAStackTy::hasExplicitDirective(
1865     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1866     unsigned Level) const {
1867   if (getStackSize() <= Level)
1868     return false;
1869   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1870   return DPred(StackElem.Directive);
1871 }
1872 
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1873 bool DSAStackTy::hasDirective(
1874     const llvm::function_ref<bool(OpenMPDirectiveKind,
1875                                   const DeclarationNameInfo &, SourceLocation)>
1876         DPred,
1877     bool FromParent) const {
1878   // We look only in the enclosing region.
1879   size_t Skip = FromParent ? 2 : 1;
1880   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1881        I != E; ++I) {
1882     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1883       return true;
1884   }
1885   return false;
1886 }
1887 
InitDataSharingAttributesStack()1888 void Sema::InitDataSharingAttributesStack() {
1889   VarDataSharingAttributesStack = new DSAStackTy(*this);
1890 }
1891 
1892 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1893 
pushOpenMPFunctionRegion()1894 void Sema::pushOpenMPFunctionRegion() {
1895   DSAStack->pushFunction();
1896 }
1897 
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1898 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1899   DSAStack->popFunction(OldFSI);
1900 }
1901 
isOpenMPDeviceDelayedContext(Sema & S)1902 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1903   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1904          "Expected OpenMP device compilation.");
1905   return !S.isInOpenMPTargetExecutionDirective();
1906 }
1907 
1908 namespace {
1909 /// Status of the function emission on the host/device.
1910 enum class FunctionEmissionStatus {
1911   Emitted,
1912   Discarded,
1913   Unknown,
1914 };
1915 } // anonymous namespace
1916 
diagIfOpenMPDeviceCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)1917 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1918                                                          unsigned DiagID,
1919                                                          FunctionDecl *FD) {
1920   assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1921          "Expected OpenMP device compilation.");
1922 
1923   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1924   if (FD) {
1925     FunctionEmissionStatus FES = getEmissionStatus(FD);
1926     switch (FES) {
1927     case FunctionEmissionStatus::Emitted:
1928       Kind = SemaDiagnosticBuilder::K_Immediate;
1929       break;
1930     case FunctionEmissionStatus::Unknown:
1931       // TODO: We should always delay diagnostics here in case a target
1932       //       region is in a function we do not emit. However, as the
1933       //       current diagnostics are associated with the function containing
1934       //       the target region and we do not emit that one, we would miss out
1935       //       on diagnostics for the target region itself. We need to anchor
1936       //       the diagnostics with the new generated function *or* ensure we
1937       //       emit diagnostics associated with the surrounding function.
1938       Kind = isOpenMPDeviceDelayedContext(*this)
1939                  ? SemaDiagnosticBuilder::K_Deferred
1940                  : SemaDiagnosticBuilder::K_Immediate;
1941       break;
1942     case FunctionEmissionStatus::TemplateDiscarded:
1943     case FunctionEmissionStatus::OMPDiscarded:
1944       Kind = SemaDiagnosticBuilder::K_Nop;
1945       break;
1946     case FunctionEmissionStatus::CUDADiscarded:
1947       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1948       break;
1949     }
1950   }
1951 
1952   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1953 }
1954 
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)1955 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1956                                                        unsigned DiagID,
1957                                                        FunctionDecl *FD) {
1958   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1959          "Expected OpenMP host compilation.");
1960 
1961   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1962   if (FD) {
1963     FunctionEmissionStatus FES = getEmissionStatus(FD);
1964     switch (FES) {
1965     case FunctionEmissionStatus::Emitted:
1966       Kind = SemaDiagnosticBuilder::K_Immediate;
1967       break;
1968     case FunctionEmissionStatus::Unknown:
1969       Kind = SemaDiagnosticBuilder::K_Deferred;
1970       break;
1971     case FunctionEmissionStatus::TemplateDiscarded:
1972     case FunctionEmissionStatus::OMPDiscarded:
1973     case FunctionEmissionStatus::CUDADiscarded:
1974       Kind = SemaDiagnosticBuilder::K_Nop;
1975       break;
1976     }
1977   }
1978 
1979   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1980 }
1981 
1982 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)1983 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1984   if (LO.OpenMP <= 45) {
1985     if (VD->getType().getNonReferenceType()->isScalarType())
1986       return OMPC_DEFAULTMAP_scalar;
1987     return OMPC_DEFAULTMAP_aggregate;
1988   }
1989   if (VD->getType().getNonReferenceType()->isAnyPointerType())
1990     return OMPC_DEFAULTMAP_pointer;
1991   if (VD->getType().getNonReferenceType()->isScalarType())
1992     return OMPC_DEFAULTMAP_scalar;
1993   return OMPC_DEFAULTMAP_aggregate;
1994 }
1995 
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const1996 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1997                                  unsigned OpenMPCaptureLevel) const {
1998   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1999 
2000   ASTContext &Ctx = getASTContext();
2001   bool IsByRef = true;
2002 
2003   // Find the directive that is associated with the provided scope.
2004   D = cast<ValueDecl>(D->getCanonicalDecl());
2005   QualType Ty = D->getType();
2006 
2007   bool IsVariableUsedInMapClause = false;
2008   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2009     // This table summarizes how a given variable should be passed to the device
2010     // given its type and the clauses where it appears. This table is based on
2011     // the description in OpenMP 4.5 [2.10.4, target Construct] and
2012     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2013     //
2014     // =========================================================================
2015     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2016     // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
2017     // =========================================================================
2018     // | scl  |               |     |       |       -       |          | bycopy|
2019     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2020     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2021     // | scl  |       x       |     |       |       -       |          | byref |
2022     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2023     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2024     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2025     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2026     //
2027     // | agg  |      n.a.     |     |       |       -       |          | byref |
2028     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2029     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2030     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2031     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2032     //
2033     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2034     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2035     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2036     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2037     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2038     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2039     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2040     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2041     // =========================================================================
2042     // Legend:
2043     //  scl - scalar
2044     //  ptr - pointer
2045     //  agg - aggregate
2046     //  x - applies
2047     //  - - invalid in this combination
2048     //  [] - mapped with an array section
2049     //  byref - should be mapped by reference
2050     //  byval - should be mapped by value
2051     //  null - initialize a local variable to null on the device
2052     //
2053     // Observations:
2054     //  - All scalar declarations that show up in a map clause have to be passed
2055     //    by reference, because they may have been mapped in the enclosing data
2056     //    environment.
2057     //  - If the scalar value does not fit the size of uintptr, it has to be
2058     //    passed by reference, regardless the result in the table above.
2059     //  - For pointers mapped by value that have either an implicit map or an
2060     //    array section, the runtime library may pass the NULL value to the
2061     //    device instead of the value passed to it by the compiler.
2062 
2063     if (Ty->isReferenceType())
2064       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2065 
2066     // Locate map clauses and see if the variable being captured is referred to
2067     // in any of those clauses. Here we only care about variables, not fields,
2068     // because fields are part of aggregates.
2069     bool IsVariableAssociatedWithSection = false;
2070 
2071     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2072         D, Level,
2073         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2074             OMPClauseMappableExprCommon::MappableExprComponentListRef
2075                 MapExprComponents,
2076             OpenMPClauseKind WhereFoundClauseKind) {
2077           // Only the map clause information influences how a variable is
2078           // captured. E.g. is_device_ptr does not require changing the default
2079           // behavior.
2080           if (WhereFoundClauseKind != OMPC_map)
2081             return false;
2082 
2083           auto EI = MapExprComponents.rbegin();
2084           auto EE = MapExprComponents.rend();
2085 
2086           assert(EI != EE && "Invalid map expression!");
2087 
2088           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2089             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2090 
2091           ++EI;
2092           if (EI == EE)
2093             return false;
2094 
2095           if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2096               isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2097               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2098               isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2099             IsVariableAssociatedWithSection = true;
2100             // There is nothing more we need to know about this variable.
2101             return true;
2102           }
2103 
2104           // Keep looking for more map info.
2105           return false;
2106         });
2107 
2108     if (IsVariableUsedInMapClause) {
2109       // If variable is identified in a map clause it is always captured by
2110       // reference except if it is a pointer that is dereferenced somehow.
2111       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2112     } else {
2113       // By default, all the data that has a scalar type is mapped by copy
2114       // (except for reduction variables).
2115       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2116       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2117                  !Ty->isAnyPointerType()) ||
2118                 !Ty->isScalarType() ||
2119                 DSAStack->isDefaultmapCapturedByRef(
2120                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2121                 DSAStack->hasExplicitDSA(
2122                     D,
2123                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2124                       return K == OMPC_reduction && !AppliedToPointee;
2125                     },
2126                     Level);
2127     }
2128   }
2129 
2130   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2131     IsByRef =
2132         ((IsVariableUsedInMapClause &&
2133           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2134               OMPD_target) ||
2135          !(DSAStack->hasExplicitDSA(
2136                D,
2137                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2138                  return K == OMPC_firstprivate ||
2139                         (K == OMPC_reduction && AppliedToPointee);
2140                },
2141                Level, /*NotLastprivate=*/true) ||
2142            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2143         // If the variable is artificial and must be captured by value - try to
2144         // capture by value.
2145         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2146           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2147         // If the variable is implicitly firstprivate and scalar - capture by
2148         // copy
2149         !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2150           !DSAStack->hasExplicitDSA(
2151               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2152               Level) &&
2153           !DSAStack->isLoopControlVariable(D, Level).first);
2154   }
2155 
2156   // When passing data by copy, we need to make sure it fits the uintptr size
2157   // and alignment, because the runtime library only deals with uintptr types.
2158   // If it does not fit the uintptr size, we need to pass the data by reference
2159   // instead.
2160   if (!IsByRef &&
2161       (Ctx.getTypeSizeInChars(Ty) >
2162            Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2163        Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2164     IsByRef = true;
2165   }
2166 
2167   return IsByRef;
2168 }
2169 
getOpenMPNestingLevel() const2170 unsigned Sema::getOpenMPNestingLevel() const {
2171   assert(getLangOpts().OpenMP);
2172   return DSAStack->getNestingLevel();
2173 }
2174 
isInOpenMPTargetExecutionDirective() const2175 bool Sema::isInOpenMPTargetExecutionDirective() const {
2176   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2177           !DSAStack->isClauseParsingMode()) ||
2178          DSAStack->hasDirective(
2179              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2180                 SourceLocation) -> bool {
2181                return isOpenMPTargetExecutionDirective(K);
2182              },
2183              false);
2184 }
2185 
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2186 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2187                                     unsigned StopAt) {
2188   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2189   D = getCanonicalDecl(D);
2190 
2191   auto *VD = dyn_cast<VarDecl>(D);
2192   // Do not capture constexpr variables.
2193   if (VD && VD->isConstexpr())
2194     return nullptr;
2195 
2196   // If we want to determine whether the variable should be captured from the
2197   // perspective of the current capturing scope, and we've already left all the
2198   // capturing scopes of the top directive on the stack, check from the
2199   // perspective of its parent directive (if any) instead.
2200   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2201       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2202 
2203   // If we are attempting to capture a global variable in a directive with
2204   // 'target' we return true so that this global is also mapped to the device.
2205   //
2206   if (VD && !VD->hasLocalStorage() &&
2207       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2208     if (isInOpenMPTargetExecutionDirective()) {
2209       DSAStackTy::DSAVarData DVarTop =
2210           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2211       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2212         return VD;
2213       // If the declaration is enclosed in a 'declare target' directive,
2214       // then it should not be captured.
2215       //
2216       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2217         return nullptr;
2218       CapturedRegionScopeInfo *CSI = nullptr;
2219       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2220                llvm::reverse(FunctionScopes),
2221                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2222         if (!isa<CapturingScopeInfo>(FSI))
2223           return nullptr;
2224         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2225           if (RSI->CapRegionKind == CR_OpenMP) {
2226             CSI = RSI;
2227             break;
2228           }
2229       }
2230       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2231       SmallVector<OpenMPDirectiveKind, 4> Regions;
2232       getOpenMPCaptureRegions(Regions,
2233                               DSAStack->getDirective(CSI->OpenMPLevel));
2234       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2235         return VD;
2236     }
2237     if (isInOpenMPDeclareTargetContext()) {
2238       // Try to mark variable as declare target if it is used in capturing
2239       // regions.
2240       if (LangOpts.OpenMP <= 45 &&
2241           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2242         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2243       return nullptr;
2244     }
2245   }
2246 
2247   if (CheckScopeInfo) {
2248     bool OpenMPFound = false;
2249     for (unsigned I = StopAt + 1; I > 0; --I) {
2250       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2251       if(!isa<CapturingScopeInfo>(FSI))
2252         return nullptr;
2253       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2254         if (RSI->CapRegionKind == CR_OpenMP) {
2255           OpenMPFound = true;
2256           break;
2257         }
2258     }
2259     if (!OpenMPFound)
2260       return nullptr;
2261   }
2262 
2263   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2264       (!DSAStack->isClauseParsingMode() ||
2265        DSAStack->getParentDirective() != OMPD_unknown)) {
2266     auto &&Info = DSAStack->isLoopControlVariable(D);
2267     if (Info.first ||
2268         (VD && VD->hasLocalStorage() &&
2269          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2270         (VD && DSAStack->isForceVarCapturing()))
2271       return VD ? VD : Info.second;
2272     DSAStackTy::DSAVarData DVarTop =
2273         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2274     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2275         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2276       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2277     // Threadprivate variables must not be captured.
2278     if (isOpenMPThreadPrivate(DVarTop.CKind))
2279       return nullptr;
2280     // The variable is not private or it is the variable in the directive with
2281     // default(none) clause and not used in any clause.
2282     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2283         D,
2284         [](OpenMPClauseKind C, bool AppliedToPointee) {
2285           return isOpenMPPrivate(C) && !AppliedToPointee;
2286         },
2287         [](OpenMPDirectiveKind) { return true; },
2288         DSAStack->isClauseParsingMode());
2289     // Global shared must not be captured.
2290     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2291         ((DSAStack->getDefaultDSA() != DSA_none &&
2292           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2293          DVarTop.CKind == OMPC_shared))
2294       return nullptr;
2295     if (DVarPrivate.CKind != OMPC_unknown ||
2296         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2297                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2298       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2299   }
2300   return nullptr;
2301 }
2302 
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2303 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2304                                         unsigned Level) const {
2305   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2306 }
2307 
startOpenMPLoop()2308 void Sema::startOpenMPLoop() {
2309   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2310   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2311     DSAStack->loopInit();
2312 }
2313 
startOpenMPCXXRangeFor()2314 void Sema::startOpenMPCXXRangeFor() {
2315   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2316   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2317     DSAStack->resetPossibleLoopCounter();
2318     DSAStack->loopStart();
2319   }
2320 }
2321 
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2322 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2323                                            unsigned CapLevel) const {
2324   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2325   if (DSAStack->hasExplicitDirective(
2326           [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2327           Level)) {
2328     bool IsTriviallyCopyable =
2329         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2330         !D->getType()
2331              .getNonReferenceType()
2332              .getCanonicalType()
2333              ->getAsCXXRecordDecl();
2334     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2335     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2336     getOpenMPCaptureRegions(CaptureRegions, DKind);
2337     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2338         (IsTriviallyCopyable ||
2339          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2340       if (DSAStack->hasExplicitDSA(
2341               D,
2342               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2343               Level, /*NotLastprivate=*/true))
2344         return OMPC_firstprivate;
2345       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2346       if (DVar.CKind != OMPC_shared &&
2347           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2348         DSAStack->addImplicitTaskFirstprivate(Level, D);
2349         return OMPC_firstprivate;
2350       }
2351     }
2352   }
2353   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2354     if (DSAStack->getAssociatedLoops() > 0 &&
2355         !DSAStack->isLoopStarted()) {
2356       DSAStack->resetPossibleLoopCounter(D);
2357       DSAStack->loopStart();
2358       return OMPC_private;
2359     }
2360     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2361          DSAStack->isLoopControlVariable(D).first) &&
2362         !DSAStack->hasExplicitDSA(
2363             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2364             Level) &&
2365         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2366       return OMPC_private;
2367   }
2368   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2369     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2370         DSAStack->isForceVarCapturing() &&
2371         !DSAStack->hasExplicitDSA(
2372             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2373             Level))
2374       return OMPC_private;
2375   }
2376   // User-defined allocators are private since they must be defined in the
2377   // context of target region.
2378   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2379       DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2380           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2381           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2382     return OMPC_private;
2383   return (DSAStack->hasExplicitDSA(
2384               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2385               Level) ||
2386           (DSAStack->isClauseParsingMode() &&
2387            DSAStack->getClauseParsingMode() == OMPC_private) ||
2388           // Consider taskgroup reduction descriptor variable a private
2389           // to avoid possible capture in the region.
2390           (DSAStack->hasExplicitDirective(
2391                [](OpenMPDirectiveKind K) {
2392                  return K == OMPD_taskgroup ||
2393                         ((isOpenMPParallelDirective(K) ||
2394                           isOpenMPWorksharingDirective(K)) &&
2395                          !isOpenMPSimdDirective(K));
2396                },
2397                Level) &&
2398            DSAStack->isTaskgroupReductionRef(D, Level)))
2399              ? OMPC_private
2400              : OMPC_unknown;
2401 }
2402 
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2403 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2404                                 unsigned Level) {
2405   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2406   D = getCanonicalDecl(D);
2407   OpenMPClauseKind OMPC = OMPC_unknown;
2408   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2409     const unsigned NewLevel = I - 1;
2410     if (DSAStack->hasExplicitDSA(
2411             D,
2412             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2413               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2414                 OMPC = K;
2415                 return true;
2416               }
2417               return false;
2418             },
2419             NewLevel))
2420       break;
2421     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2422             D, NewLevel,
2423             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2424                OpenMPClauseKind) { return true; })) {
2425       OMPC = OMPC_map;
2426       break;
2427     }
2428     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2429                                        NewLevel)) {
2430       OMPC = OMPC_map;
2431       if (DSAStack->mustBeFirstprivateAtLevel(
2432               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2433         OMPC = OMPC_firstprivate;
2434       break;
2435     }
2436   }
2437   if (OMPC != OMPC_unknown)
2438     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2439 }
2440 
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2441 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2442                                       unsigned CaptureLevel) const {
2443   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2444   // Return true if the current level is no longer enclosed in a target region.
2445 
2446   SmallVector<OpenMPDirectiveKind, 4> Regions;
2447   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2448   const auto *VD = dyn_cast<VarDecl>(D);
2449   return VD && !VD->hasLocalStorage() &&
2450          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2451                                         Level) &&
2452          Regions[CaptureLevel] != OMPD_task;
2453 }
2454 
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2455 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2456                                       unsigned CaptureLevel) const {
2457   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2458   // Return true if the current level is no longer enclosed in a target region.
2459 
2460   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2461     if (!VD->hasLocalStorage()) {
2462       if (isInOpenMPTargetExecutionDirective())
2463         return true;
2464       DSAStackTy::DSAVarData TopDVar =
2465           DSAStack->getTopDSA(D, /*FromParent=*/false);
2466       unsigned NumLevels =
2467           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2468       if (Level == 0)
2469         return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2470       do {
2471         --Level;
2472         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2473         if (DVar.CKind != OMPC_shared)
2474           return true;
2475       } while (Level > 0);
2476     }
2477   }
2478   return true;
2479 }
2480 
DestroyDataSharingAttributesStack()2481 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2482 
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2483 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2484                                           OMPTraitInfo &TI) {
2485   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2486 }
2487 
ActOnOpenMPEndDeclareVariant()2488 void Sema::ActOnOpenMPEndDeclareVariant() {
2489   assert(isInOpenMPDeclareVariantScope() &&
2490          "Not in OpenMP declare variant scope!");
2491 
2492   OMPDeclareVariantScopes.pop_back();
2493 }
2494 
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2495 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2496                                          const FunctionDecl *Callee,
2497                                          SourceLocation Loc) {
2498   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2499   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2500       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2501   // Ignore host functions during device analyzis.
2502   if (LangOpts.OpenMPIsDevice &&
2503       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2504     return;
2505   // Ignore nohost functions during host analyzis.
2506   if (!LangOpts.OpenMPIsDevice && DevTy &&
2507       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2508     return;
2509   const FunctionDecl *FD = Callee->getMostRecentDecl();
2510   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2511   if (LangOpts.OpenMPIsDevice && DevTy &&
2512       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2513     // Diagnose host function called during device codegen.
2514     StringRef HostDevTy =
2515         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2516     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2517     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2518          diag::note_omp_marked_device_type_here)
2519         << HostDevTy;
2520     return;
2521   }
2522       if (!LangOpts.OpenMPIsDevice && DevTy &&
2523           *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2524         // Diagnose nohost function called during host codegen.
2525         StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2526             OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2527         Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2528         Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2529              diag::note_omp_marked_device_type_here)
2530             << NoHostDevTy;
2531       }
2532 }
2533 
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2534 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2535                                const DeclarationNameInfo &DirName,
2536                                Scope *CurScope, SourceLocation Loc) {
2537   DSAStack->push(DKind, DirName, CurScope, Loc);
2538   PushExpressionEvaluationContext(
2539       ExpressionEvaluationContext::PotentiallyEvaluated);
2540 }
2541 
StartOpenMPClause(OpenMPClauseKind K)2542 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2543   DSAStack->setClauseParsingMode(K);
2544 }
2545 
EndOpenMPClause()2546 void Sema::EndOpenMPClause() {
2547   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2548   CleanupVarDeclMarking();
2549 }
2550 
2551 static std::pair<ValueDecl *, bool>
2552 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2553                SourceRange &ERange, bool AllowArraySection = false);
2554 
2555 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2556 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2557                                   ArrayRef<OMPClause *> Clauses) {
2558   bool InscanFound = false;
2559   SourceLocation InscanLoc;
2560   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2561   // A reduction clause without the inscan reduction-modifier may not appear on
2562   // a construct on which a reduction clause with the inscan reduction-modifier
2563   // appears.
2564   for (OMPClause *C : Clauses) {
2565     if (C->getClauseKind() != OMPC_reduction)
2566       continue;
2567     auto *RC = cast<OMPReductionClause>(C);
2568     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2569       InscanFound = true;
2570       InscanLoc = RC->getModifierLoc();
2571       continue;
2572     }
2573     if (RC->getModifier() == OMPC_REDUCTION_task) {
2574       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2575       // A reduction clause with the task reduction-modifier may only appear on
2576       // a parallel construct, a worksharing construct or a combined or
2577       // composite construct for which any of the aforementioned constructs is a
2578       // constituent construct and simd or loop are not constituent constructs.
2579       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2580       if (!(isOpenMPParallelDirective(CurDir) ||
2581             isOpenMPWorksharingDirective(CurDir)) ||
2582           isOpenMPSimdDirective(CurDir))
2583         S.Diag(RC->getModifierLoc(),
2584                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2585       continue;
2586     }
2587   }
2588   if (InscanFound) {
2589     for (OMPClause *C : Clauses) {
2590       if (C->getClauseKind() != OMPC_reduction)
2591         continue;
2592       auto *RC = cast<OMPReductionClause>(C);
2593       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2594         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2595                    ? RC->getBeginLoc()
2596                    : RC->getModifierLoc(),
2597                diag::err_omp_inscan_reduction_expected);
2598         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2599         continue;
2600       }
2601       for (Expr *Ref : RC->varlists()) {
2602         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2603         SourceLocation ELoc;
2604         SourceRange ERange;
2605         Expr *SimpleRefExpr = Ref;
2606         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2607                                   /*AllowArraySection=*/true);
2608         ValueDecl *D = Res.first;
2609         if (!D)
2610           continue;
2611         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2612           S.Diag(Ref->getExprLoc(),
2613                  diag::err_omp_reduction_not_inclusive_exclusive)
2614               << Ref->getSourceRange();
2615         }
2616       }
2617     }
2618   }
2619 }
2620 
2621 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2622                                  ArrayRef<OMPClause *> Clauses);
2623 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2624                                  bool WithInit);
2625 
2626 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2627                               const ValueDecl *D,
2628                               const DSAStackTy::DSAVarData &DVar,
2629                               bool IsLoopIterVar = false);
2630 
EndOpenMPDSABlock(Stmt * CurDirective)2631 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2632   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2633   //  A variable of class type (or array thereof) that appears in a lastprivate
2634   //  clause requires an accessible, unambiguous default constructor for the
2635   //  class type, unless the list item is also specified in a firstprivate
2636   //  clause.
2637   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2638     for (OMPClause *C : D->clauses()) {
2639       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2640         SmallVector<Expr *, 8> PrivateCopies;
2641         for (Expr *DE : Clause->varlists()) {
2642           if (DE->isValueDependent() || DE->isTypeDependent()) {
2643             PrivateCopies.push_back(nullptr);
2644             continue;
2645           }
2646           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2647           auto *VD = cast<VarDecl>(DRE->getDecl());
2648           QualType Type = VD->getType().getNonReferenceType();
2649           const DSAStackTy::DSAVarData DVar =
2650               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2651           if (DVar.CKind == OMPC_lastprivate) {
2652             // Generate helper private variable and initialize it with the
2653             // default value. The address of the original variable is replaced
2654             // by the address of the new private variable in CodeGen. This new
2655             // variable is not added to IdResolver, so the code in the OpenMP
2656             // region uses original variable for proper diagnostics.
2657             VarDecl *VDPrivate = buildVarDecl(
2658                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2659                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2660             ActOnUninitializedDecl(VDPrivate);
2661             if (VDPrivate->isInvalidDecl()) {
2662               PrivateCopies.push_back(nullptr);
2663               continue;
2664             }
2665             PrivateCopies.push_back(buildDeclRefExpr(
2666                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2667           } else {
2668             // The variable is also a firstprivate, so initialization sequence
2669             // for private copy is generated already.
2670             PrivateCopies.push_back(nullptr);
2671           }
2672         }
2673         Clause->setPrivateCopies(PrivateCopies);
2674         continue;
2675       }
2676       // Finalize nontemporal clause by handling private copies, if any.
2677       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2678         SmallVector<Expr *, 8> PrivateRefs;
2679         for (Expr *RefExpr : Clause->varlists()) {
2680           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2681           SourceLocation ELoc;
2682           SourceRange ERange;
2683           Expr *SimpleRefExpr = RefExpr;
2684           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2685           if (Res.second)
2686             // It will be analyzed later.
2687             PrivateRefs.push_back(RefExpr);
2688           ValueDecl *D = Res.first;
2689           if (!D)
2690             continue;
2691 
2692           const DSAStackTy::DSAVarData DVar =
2693               DSAStack->getTopDSA(D, /*FromParent=*/false);
2694           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2695                                                  : SimpleRefExpr);
2696         }
2697         Clause->setPrivateRefs(PrivateRefs);
2698         continue;
2699       }
2700       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2701         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2702           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2703           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2704           if (!DRE)
2705             continue;
2706           ValueDecl *VD = DRE->getDecl();
2707           if (!VD || !isa<VarDecl>(VD))
2708             continue;
2709           DSAStackTy::DSAVarData DVar =
2710               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2711           // OpenMP [2.12.5, target Construct]
2712           // Memory allocators that appear in a uses_allocators clause cannot
2713           // appear in other data-sharing attribute clauses or data-mapping
2714           // attribute clauses in the same construct.
2715           Expr *MapExpr = nullptr;
2716           if (DVar.RefExpr ||
2717               DSAStack->checkMappableExprComponentListsForDecl(
2718                   VD, /*CurrentRegionOnly=*/true,
2719                   [VD, &MapExpr](
2720                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2721                           MapExprComponents,
2722                       OpenMPClauseKind C) {
2723                     auto MI = MapExprComponents.rbegin();
2724                     auto ME = MapExprComponents.rend();
2725                     if (MI != ME &&
2726                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2727                             VD->getCanonicalDecl()) {
2728                       MapExpr = MI->getAssociatedExpression();
2729                       return true;
2730                     }
2731                     return false;
2732                   })) {
2733             Diag(D.Allocator->getExprLoc(),
2734                  diag::err_omp_allocator_used_in_clauses)
2735                 << D.Allocator->getSourceRange();
2736             if (DVar.RefExpr)
2737               reportOriginalDsa(*this, DSAStack, VD, DVar);
2738             else
2739               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2740                   << MapExpr->getSourceRange();
2741           }
2742         }
2743         continue;
2744       }
2745     }
2746     // Check allocate clauses.
2747     if (!CurContext->isDependentContext())
2748       checkAllocateClauses(*this, DSAStack, D->clauses());
2749     checkReductionClauses(*this, DSAStack, D->clauses());
2750   }
2751 
2752   DSAStack->pop();
2753   DiscardCleanupsInEvaluationContext();
2754   PopExpressionEvaluationContext();
2755 }
2756 
2757 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2758                                      Expr *NumIterations, Sema &SemaRef,
2759                                      Scope *S, DSAStackTy *Stack);
2760 
2761 namespace {
2762 
2763 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2764 private:
2765   Sema &SemaRef;
2766 
2767 public:
VarDeclFilterCCC(Sema & S)2768   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2769   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2770     NamedDecl *ND = Candidate.getCorrectionDecl();
2771     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2772       return VD->hasGlobalStorage() &&
2773              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2774                                    SemaRef.getCurScope());
2775     }
2776     return false;
2777   }
2778 
clone()2779   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2780     return std::make_unique<VarDeclFilterCCC>(*this);
2781   }
2782 
2783 };
2784 
2785 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2786 private:
2787   Sema &SemaRef;
2788 
2789 public:
VarOrFuncDeclFilterCCC(Sema & S)2790   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2791   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2792     NamedDecl *ND = Candidate.getCorrectionDecl();
2793     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2794                isa<FunctionDecl>(ND))) {
2795       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2796                                    SemaRef.getCurScope());
2797     }
2798     return false;
2799   }
2800 
clone()2801   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2802     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2803   }
2804 };
2805 
2806 } // namespace
2807 
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2808 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2809                                          CXXScopeSpec &ScopeSpec,
2810                                          const DeclarationNameInfo &Id,
2811                                          OpenMPDirectiveKind Kind) {
2812   LookupResult Lookup(*this, Id, LookupOrdinaryName);
2813   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2814 
2815   if (Lookup.isAmbiguous())
2816     return ExprError();
2817 
2818   VarDecl *VD;
2819   if (!Lookup.isSingleResult()) {
2820     VarDeclFilterCCC CCC(*this);
2821     if (TypoCorrection Corrected =
2822             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2823                         CTK_ErrorRecovery)) {
2824       diagnoseTypo(Corrected,
2825                    PDiag(Lookup.empty()
2826                              ? diag::err_undeclared_var_use_suggest
2827                              : diag::err_omp_expected_var_arg_suggest)
2828                        << Id.getName());
2829       VD = Corrected.getCorrectionDeclAs<VarDecl>();
2830     } else {
2831       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2832                                        : diag::err_omp_expected_var_arg)
2833           << Id.getName();
2834       return ExprError();
2835     }
2836   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2837     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2838     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2839     return ExprError();
2840   }
2841   Lookup.suppressDiagnostics();
2842 
2843   // OpenMP [2.9.2, Syntax, C/C++]
2844   //   Variables must be file-scope, namespace-scope, or static block-scope.
2845   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2846     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2847         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2848     bool IsDecl =
2849         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2850     Diag(VD->getLocation(),
2851          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2852         << VD;
2853     return ExprError();
2854   }
2855 
2856   VarDecl *CanonicalVD = VD->getCanonicalDecl();
2857   NamedDecl *ND = CanonicalVD;
2858   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2859   //   A threadprivate directive for file-scope variables must appear outside
2860   //   any definition or declaration.
2861   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2862       !getCurLexicalContext()->isTranslationUnit()) {
2863     Diag(Id.getLoc(), diag::err_omp_var_scope)
2864         << getOpenMPDirectiveName(Kind) << VD;
2865     bool IsDecl =
2866         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2867     Diag(VD->getLocation(),
2868          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2869         << VD;
2870     return ExprError();
2871   }
2872   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2873   //   A threadprivate directive for static class member variables must appear
2874   //   in the class definition, in the same scope in which the member
2875   //   variables are declared.
2876   if (CanonicalVD->isStaticDataMember() &&
2877       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2878     Diag(Id.getLoc(), diag::err_omp_var_scope)
2879         << getOpenMPDirectiveName(Kind) << VD;
2880     bool IsDecl =
2881         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2882     Diag(VD->getLocation(),
2883          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2884         << VD;
2885     return ExprError();
2886   }
2887   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2888   //   A threadprivate directive for namespace-scope variables must appear
2889   //   outside any definition or declaration other than the namespace
2890   //   definition itself.
2891   if (CanonicalVD->getDeclContext()->isNamespace() &&
2892       (!getCurLexicalContext()->isFileContext() ||
2893        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2894     Diag(Id.getLoc(), diag::err_omp_var_scope)
2895         << getOpenMPDirectiveName(Kind) << VD;
2896     bool IsDecl =
2897         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2898     Diag(VD->getLocation(),
2899          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2900         << VD;
2901     return ExprError();
2902   }
2903   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2904   //   A threadprivate directive for static block-scope variables must appear
2905   //   in the scope of the variable and not in a nested scope.
2906   if (CanonicalVD->isLocalVarDecl() && CurScope &&
2907       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2908     Diag(Id.getLoc(), diag::err_omp_var_scope)
2909         << getOpenMPDirectiveName(Kind) << VD;
2910     bool IsDecl =
2911         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2912     Diag(VD->getLocation(),
2913          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2914         << VD;
2915     return ExprError();
2916   }
2917 
2918   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2919   //   A threadprivate directive must lexically precede all references to any
2920   //   of the variables in its list.
2921   if (Kind == OMPD_threadprivate && VD->isUsed() &&
2922       !DSAStack->isThreadPrivate(VD)) {
2923     Diag(Id.getLoc(), diag::err_omp_var_used)
2924         << getOpenMPDirectiveName(Kind) << VD;
2925     return ExprError();
2926   }
2927 
2928   QualType ExprType = VD->getType().getNonReferenceType();
2929   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2930                              SourceLocation(), VD,
2931                              /*RefersToEnclosingVariableOrCapture=*/false,
2932                              Id.getLoc(), ExprType, VK_LValue);
2933 }
2934 
2935 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)2936 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2937                                         ArrayRef<Expr *> VarList) {
2938   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2939     CurContext->addDecl(D);
2940     return DeclGroupPtrTy::make(DeclGroupRef(D));
2941   }
2942   return nullptr;
2943 }
2944 
2945 namespace {
2946 class LocalVarRefChecker final
2947     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2948   Sema &SemaRef;
2949 
2950 public:
VisitDeclRefExpr(const DeclRefExpr * E)2951   bool VisitDeclRefExpr(const DeclRefExpr *E) {
2952     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2953       if (VD->hasLocalStorage()) {
2954         SemaRef.Diag(E->getBeginLoc(),
2955                      diag::err_omp_local_var_in_threadprivate_init)
2956             << E->getSourceRange();
2957         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2958             << VD << VD->getSourceRange();
2959         return true;
2960       }
2961     }
2962     return false;
2963   }
VisitStmt(const Stmt * S)2964   bool VisitStmt(const Stmt *S) {
2965     for (const Stmt *Child : S->children()) {
2966       if (Child && Visit(Child))
2967         return true;
2968     }
2969     return false;
2970   }
LocalVarRefChecker(Sema & SemaRef)2971   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2972 };
2973 } // namespace
2974 
2975 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2976 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2977   SmallVector<Expr *, 8> Vars;
2978   for (Expr *RefExpr : VarList) {
2979     auto *DE = cast<DeclRefExpr>(RefExpr);
2980     auto *VD = cast<VarDecl>(DE->getDecl());
2981     SourceLocation ILoc = DE->getExprLoc();
2982 
2983     // Mark variable as used.
2984     VD->setReferenced();
2985     VD->markUsed(Context);
2986 
2987     QualType QType = VD->getType();
2988     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2989       // It will be analyzed later.
2990       Vars.push_back(DE);
2991       continue;
2992     }
2993 
2994     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2995     //   A threadprivate variable must not have an incomplete type.
2996     if (RequireCompleteType(ILoc, VD->getType(),
2997                             diag::err_omp_threadprivate_incomplete_type)) {
2998       continue;
2999     }
3000 
3001     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3002     //   A threadprivate variable must not have a reference type.
3003     if (VD->getType()->isReferenceType()) {
3004       Diag(ILoc, diag::err_omp_ref_type_arg)
3005           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3006       bool IsDecl =
3007           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3008       Diag(VD->getLocation(),
3009            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3010           << VD;
3011       continue;
3012     }
3013 
3014     // Check if this is a TLS variable. If TLS is not being supported, produce
3015     // the corresponding diagnostic.
3016     if ((VD->getTLSKind() != VarDecl::TLS_None &&
3017          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3018            getLangOpts().OpenMPUseTLS &&
3019            getASTContext().getTargetInfo().isTLSSupported())) ||
3020         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3021          !VD->isLocalVarDecl())) {
3022       Diag(ILoc, diag::err_omp_var_thread_local)
3023           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3024       bool IsDecl =
3025           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3026       Diag(VD->getLocation(),
3027            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3028           << VD;
3029       continue;
3030     }
3031 
3032     // Check if initial value of threadprivate variable reference variable with
3033     // local storage (it is not supported by runtime).
3034     if (const Expr *Init = VD->getAnyInitializer()) {
3035       LocalVarRefChecker Checker(*this);
3036       if (Checker.Visit(Init))
3037         continue;
3038     }
3039 
3040     Vars.push_back(RefExpr);
3041     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3042     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3043         Context, SourceRange(Loc, Loc)));
3044     if (ASTMutationListener *ML = Context.getASTMutationListener())
3045       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3046   }
3047   OMPThreadPrivateDecl *D = nullptr;
3048   if (!Vars.empty()) {
3049     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3050                                      Vars);
3051     D->setAccess(AS_public);
3052   }
3053   return D;
3054 }
3055 
3056 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3057 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3058   if (!Allocator)
3059     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3060   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3061       Allocator->isInstantiationDependent() ||
3062       Allocator->containsUnexpandedParameterPack())
3063     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3064   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3065   const Expr *AE = Allocator->IgnoreParenImpCasts();
3066   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3067     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3068     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3069     llvm::FoldingSetNodeID AEId, DAEId;
3070     AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3071     DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3072     if (AEId == DAEId) {
3073       AllocatorKindRes = AllocatorKind;
3074       break;
3075     }
3076   }
3077   return AllocatorKindRes;
3078 }
3079 
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3080 static bool checkPreviousOMPAllocateAttribute(
3081     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3082     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3083   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3084     return false;
3085   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3086   Expr *PrevAllocator = A->getAllocator();
3087   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3088       getAllocatorKind(S, Stack, PrevAllocator);
3089   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3090   if (AllocatorsMatch &&
3091       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3092       Allocator && PrevAllocator) {
3093     const Expr *AE = Allocator->IgnoreParenImpCasts();
3094     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3095     llvm::FoldingSetNodeID AEId, PAEId;
3096     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3097     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3098     AllocatorsMatch = AEId == PAEId;
3099   }
3100   if (!AllocatorsMatch) {
3101     SmallString<256> AllocatorBuffer;
3102     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3103     if (Allocator)
3104       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3105     SmallString<256> PrevAllocatorBuffer;
3106     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3107     if (PrevAllocator)
3108       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3109                                  S.getPrintingPolicy());
3110 
3111     SourceLocation AllocatorLoc =
3112         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3113     SourceRange AllocatorRange =
3114         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3115     SourceLocation PrevAllocatorLoc =
3116         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3117     SourceRange PrevAllocatorRange =
3118         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3119     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3120         << (Allocator ? 1 : 0) << AllocatorStream.str()
3121         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3122         << AllocatorRange;
3123     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3124         << PrevAllocatorRange;
3125     return true;
3126   }
3127   return false;
3128 }
3129 
3130 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,SourceRange SR)3131 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3132                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3133                           Expr *Allocator, SourceRange SR) {
3134   if (VD->hasAttr<OMPAllocateDeclAttr>())
3135     return;
3136   if (Allocator &&
3137       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3138        Allocator->isInstantiationDependent() ||
3139        Allocator->containsUnexpandedParameterPack()))
3140     return;
3141   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3142                                                 Allocator, SR);
3143   VD->addAttr(A);
3144   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3145     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3146 }
3147 
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3148 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3149     SourceLocation Loc, ArrayRef<Expr *> VarList,
3150     ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3151   assert(Clauses.size() <= 1 && "Expected at most one clause.");
3152   Expr *Allocator = nullptr;
3153   if (Clauses.empty()) {
3154     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3155     // allocate directives that appear in a target region must specify an
3156     // allocator clause unless a requires directive with the dynamic_allocators
3157     // clause is present in the same compilation unit.
3158     if (LangOpts.OpenMPIsDevice &&
3159         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3160       targetDiag(Loc, diag::err_expected_allocator_clause);
3161   } else {
3162     Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3163   }
3164   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3165       getAllocatorKind(*this, DSAStack, Allocator);
3166   SmallVector<Expr *, 8> Vars;
3167   for (Expr *RefExpr : VarList) {
3168     auto *DE = cast<DeclRefExpr>(RefExpr);
3169     auto *VD = cast<VarDecl>(DE->getDecl());
3170 
3171     // Check if this is a TLS variable or global register.
3172     if (VD->getTLSKind() != VarDecl::TLS_None ||
3173         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3174         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3175          !VD->isLocalVarDecl()))
3176       continue;
3177 
3178     // If the used several times in the allocate directive, the same allocator
3179     // must be used.
3180     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3181                                           AllocatorKind, Allocator))
3182       continue;
3183 
3184     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3185     // If a list item has a static storage type, the allocator expression in the
3186     // allocator clause must be a constant expression that evaluates to one of
3187     // the predefined memory allocator values.
3188     if (Allocator && VD->hasGlobalStorage()) {
3189       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3190         Diag(Allocator->getExprLoc(),
3191              diag::err_omp_expected_predefined_allocator)
3192             << Allocator->getSourceRange();
3193         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3194                       VarDecl::DeclarationOnly;
3195         Diag(VD->getLocation(),
3196              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3197             << VD;
3198         continue;
3199       }
3200     }
3201 
3202     Vars.push_back(RefExpr);
3203     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3204                               DE->getSourceRange());
3205   }
3206   if (Vars.empty())
3207     return nullptr;
3208   if (!Owner)
3209     Owner = getCurLexicalContext();
3210   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3211   D->setAccess(AS_public);
3212   Owner->addDecl(D);
3213   return DeclGroupPtrTy::make(DeclGroupRef(D));
3214 }
3215 
3216 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3217 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3218                                    ArrayRef<OMPClause *> ClauseList) {
3219   OMPRequiresDecl *D = nullptr;
3220   if (!CurContext->isFileContext()) {
3221     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3222   } else {
3223     D = CheckOMPRequiresDecl(Loc, ClauseList);
3224     if (D) {
3225       CurContext->addDecl(D);
3226       DSAStack->addRequiresDecl(D);
3227     }
3228   }
3229   return DeclGroupPtrTy::make(DeclGroupRef(D));
3230 }
3231 
ActOnOpenMPAssumesDirective(SourceLocation Loc,OpenMPDirectiveKind DKind,ArrayRef<std::string> Assumptions,bool SkippedClauses)3232 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3233                                        OpenMPDirectiveKind DKind,
3234                                        ArrayRef<std::string> Assumptions,
3235                                        bool SkippedClauses) {
3236   if (!SkippedClauses && Assumptions.empty())
3237     Diag(Loc, diag::err_omp_no_clause_for_directive)
3238         << llvm::omp::getAllAssumeClauseOptions()
3239         << llvm::omp::getOpenMPDirectiveName(DKind);
3240 
3241   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3242   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3243     OMPAssumeScoped.push_back(AA);
3244     return;
3245   }
3246 
3247   // Global assumes without assumption clauses are ignored.
3248   if (Assumptions.empty())
3249     return;
3250 
3251   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3252          "Unexpected omp assumption directive!");
3253   OMPAssumeGlobal.push_back(AA);
3254 
3255   // The OMPAssumeGlobal scope above will take care of new declarations but
3256   // we also want to apply the assumption to existing ones, e.g., to
3257   // declarations in included headers. To this end, we traverse all existing
3258   // declaration contexts and annotate function declarations here.
3259   SmallVector<DeclContext *, 8> DeclContexts;
3260   auto *Ctx = CurContext;
3261   while (Ctx->getLexicalParent())
3262     Ctx = Ctx->getLexicalParent();
3263   DeclContexts.push_back(Ctx);
3264   while (!DeclContexts.empty()) {
3265     DeclContext *DC = DeclContexts.pop_back_val();
3266     for (auto *SubDC : DC->decls()) {
3267       if (SubDC->isInvalidDecl())
3268         continue;
3269       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3270         DeclContexts.push_back(CTD->getTemplatedDecl());
3271         for (auto *S : CTD->specializations())
3272           DeclContexts.push_back(S);
3273         continue;
3274       }
3275       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3276         DeclContexts.push_back(DC);
3277       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3278         F->addAttr(AA);
3279         continue;
3280       }
3281     }
3282   }
3283 }
3284 
ActOnOpenMPEndAssumesDirective()3285 void Sema::ActOnOpenMPEndAssumesDirective() {
3286   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3287   OMPAssumeScoped.pop_back();
3288 }
3289 
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3290 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3291                                             ArrayRef<OMPClause *> ClauseList) {
3292   /// For target specific clauses, the requires directive cannot be
3293   /// specified after the handling of any of the target regions in the
3294   /// current compilation unit.
3295   ArrayRef<SourceLocation> TargetLocations =
3296       DSAStack->getEncounteredTargetLocs();
3297   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3298   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3299     for (const OMPClause *CNew : ClauseList) {
3300       // Check if any of the requires clauses affect target regions.
3301       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3302           isa<OMPUnifiedAddressClause>(CNew) ||
3303           isa<OMPReverseOffloadClause>(CNew) ||
3304           isa<OMPDynamicAllocatorsClause>(CNew)) {
3305         Diag(Loc, diag::err_omp_directive_before_requires)
3306             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3307         for (SourceLocation TargetLoc : TargetLocations) {
3308           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3309               << "target";
3310         }
3311       } else if (!AtomicLoc.isInvalid() &&
3312                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3313         Diag(Loc, diag::err_omp_directive_before_requires)
3314             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3315         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3316             << "atomic";
3317       }
3318     }
3319   }
3320 
3321   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3322     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3323                                    ClauseList);
3324   return nullptr;
3325 }
3326 
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3327 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3328                               const ValueDecl *D,
3329                               const DSAStackTy::DSAVarData &DVar,
3330                               bool IsLoopIterVar) {
3331   if (DVar.RefExpr) {
3332     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3333         << getOpenMPClauseName(DVar.CKind);
3334     return;
3335   }
3336   enum {
3337     PDSA_StaticMemberShared,
3338     PDSA_StaticLocalVarShared,
3339     PDSA_LoopIterVarPrivate,
3340     PDSA_LoopIterVarLinear,
3341     PDSA_LoopIterVarLastprivate,
3342     PDSA_ConstVarShared,
3343     PDSA_GlobalVarShared,
3344     PDSA_TaskVarFirstprivate,
3345     PDSA_LocalVarPrivate,
3346     PDSA_Implicit
3347   } Reason = PDSA_Implicit;
3348   bool ReportHint = false;
3349   auto ReportLoc = D->getLocation();
3350   auto *VD = dyn_cast<VarDecl>(D);
3351   if (IsLoopIterVar) {
3352     if (DVar.CKind == OMPC_private)
3353       Reason = PDSA_LoopIterVarPrivate;
3354     else if (DVar.CKind == OMPC_lastprivate)
3355       Reason = PDSA_LoopIterVarLastprivate;
3356     else
3357       Reason = PDSA_LoopIterVarLinear;
3358   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3359              DVar.CKind == OMPC_firstprivate) {
3360     Reason = PDSA_TaskVarFirstprivate;
3361     ReportLoc = DVar.ImplicitDSALoc;
3362   } else if (VD && VD->isStaticLocal())
3363     Reason = PDSA_StaticLocalVarShared;
3364   else if (VD && VD->isStaticDataMember())
3365     Reason = PDSA_StaticMemberShared;
3366   else if (VD && VD->isFileVarDecl())
3367     Reason = PDSA_GlobalVarShared;
3368   else if (D->getType().isConstant(SemaRef.getASTContext()))
3369     Reason = PDSA_ConstVarShared;
3370   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3371     ReportHint = true;
3372     Reason = PDSA_LocalVarPrivate;
3373   }
3374   if (Reason != PDSA_Implicit) {
3375     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3376         << Reason << ReportHint
3377         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3378   } else if (DVar.ImplicitDSALoc.isValid()) {
3379     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3380         << getOpenMPClauseName(DVar.CKind);
3381   }
3382 }
3383 
3384 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3385 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3386                              bool IsAggregateOrDeclareTarget) {
3387   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3388   switch (M) {
3389   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3390     Kind = OMPC_MAP_alloc;
3391     break;
3392   case OMPC_DEFAULTMAP_MODIFIER_to:
3393     Kind = OMPC_MAP_to;
3394     break;
3395   case OMPC_DEFAULTMAP_MODIFIER_from:
3396     Kind = OMPC_MAP_from;
3397     break;
3398   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3399     Kind = OMPC_MAP_tofrom;
3400     break;
3401   case OMPC_DEFAULTMAP_MODIFIER_present:
3402     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3403     // If implicit-behavior is present, each variable referenced in the
3404     // construct in the category specified by variable-category is treated as if
3405     // it had been listed in a map clause with the map-type of alloc and
3406     // map-type-modifier of present.
3407     Kind = OMPC_MAP_alloc;
3408     break;
3409   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3410   case OMPC_DEFAULTMAP_MODIFIER_last:
3411     llvm_unreachable("Unexpected defaultmap implicit behavior");
3412   case OMPC_DEFAULTMAP_MODIFIER_none:
3413   case OMPC_DEFAULTMAP_MODIFIER_default:
3414   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3415     // IsAggregateOrDeclareTarget could be true if:
3416     // 1. the implicit behavior for aggregate is tofrom
3417     // 2. it's a declare target link
3418     if (IsAggregateOrDeclareTarget) {
3419       Kind = OMPC_MAP_tofrom;
3420       break;
3421     }
3422     llvm_unreachable("Unexpected defaultmap implicit behavior");
3423   }
3424   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3425   return Kind;
3426 }
3427 
3428 namespace {
3429 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3430   DSAStackTy *Stack;
3431   Sema &SemaRef;
3432   bool ErrorFound = false;
3433   bool TryCaptureCXXThisMembers = false;
3434   CapturedStmt *CS = nullptr;
3435   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3436   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3437   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3438   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3439       ImplicitMapModifier[DefaultmapKindNum];
3440   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3441   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3442 
VisitSubCaptures(OMPExecutableDirective * S)3443   void VisitSubCaptures(OMPExecutableDirective *S) {
3444     // Check implicitly captured variables.
3445     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3446       return;
3447     if (S->getDirectiveKind() == OMPD_atomic ||
3448         S->getDirectiveKind() == OMPD_critical ||
3449         S->getDirectiveKind() == OMPD_section ||
3450         S->getDirectiveKind() == OMPD_master ||
3451         S->getDirectiveKind() == OMPD_masked ||
3452         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3453       Visit(S->getAssociatedStmt());
3454       return;
3455     }
3456     visitSubCaptures(S->getInnermostCapturedStmt());
3457     // Try to capture inner this->member references to generate correct mappings
3458     // and diagnostics.
3459     if (TryCaptureCXXThisMembers ||
3460         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3461          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3462                       [](const CapturedStmt::Capture &C) {
3463                         return C.capturesThis();
3464                       }))) {
3465       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3466       TryCaptureCXXThisMembers = true;
3467       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3468       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3469     }
3470     // In tasks firstprivates are not captured anymore, need to analyze them
3471     // explicitly.
3472     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3473         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3474       for (OMPClause *C : S->clauses())
3475         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3476           for (Expr *Ref : FC->varlists())
3477             Visit(Ref);
3478         }
3479     }
3480   }
3481 
3482 public:
VisitDeclRefExpr(DeclRefExpr * E)3483   void VisitDeclRefExpr(DeclRefExpr *E) {
3484     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3485         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3486         E->isInstantiationDependent())
3487       return;
3488     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3489       // Check the datasharing rules for the expressions in the clauses.
3490       if (!CS) {
3491         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3492           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3493             Visit(CED->getInit());
3494             return;
3495           }
3496       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3497         // Do not analyze internal variables and do not enclose them into
3498         // implicit clauses.
3499         return;
3500       VD = VD->getCanonicalDecl();
3501       // Skip internally declared variables.
3502       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3503           !Stack->isImplicitTaskFirstprivate(VD))
3504         return;
3505       // Skip allocators in uses_allocators clauses.
3506       if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3507         return;
3508 
3509       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3510       // Check if the variable has explicit DSA set and stop analysis if it so.
3511       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3512         return;
3513 
3514       // Skip internally declared static variables.
3515       llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3516           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3517       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3518           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3519            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3520           !Stack->isImplicitTaskFirstprivate(VD))
3521         return;
3522 
3523       SourceLocation ELoc = E->getExprLoc();
3524       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3525       // The default(none) clause requires that each variable that is referenced
3526       // in the construct, and does not have a predetermined data-sharing
3527       // attribute, must have its data-sharing attribute explicitly determined
3528       // by being listed in a data-sharing attribute clause.
3529       if (DVar.CKind == OMPC_unknown &&
3530           (Stack->getDefaultDSA() == DSA_none ||
3531            Stack->getDefaultDSA() == DSA_firstprivate) &&
3532           isImplicitOrExplicitTaskingRegion(DKind) &&
3533           VarsWithInheritedDSA.count(VD) == 0) {
3534         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3535         if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3536           DSAStackTy::DSAVarData DVar =
3537               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3538           InheritedDSA = DVar.CKind == OMPC_unknown;
3539         }
3540         if (InheritedDSA)
3541           VarsWithInheritedDSA[VD] = E;
3542         return;
3543       }
3544 
3545       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3546       // If implicit-behavior is none, each variable referenced in the
3547       // construct that does not have a predetermined data-sharing attribute
3548       // and does not appear in a to or link clause on a declare target
3549       // directive must be listed in a data-mapping attribute clause, a
3550       // data-haring attribute clause (including a data-sharing attribute
3551       // clause on a combined construct where target. is one of the
3552       // constituent constructs), or an is_device_ptr clause.
3553       OpenMPDefaultmapClauseKind ClauseKind =
3554           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3555       if (SemaRef.getLangOpts().OpenMP >= 50) {
3556         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3557                               OMPC_DEFAULTMAP_MODIFIER_none;
3558         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3559             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3560           // Only check for data-mapping attribute and is_device_ptr here
3561           // since we have already make sure that the declaration does not
3562           // have a data-sharing attribute above
3563           if (!Stack->checkMappableExprComponentListsForDecl(
3564                   VD, /*CurrentRegionOnly=*/true,
3565                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3566                            MapExprComponents,
3567                        OpenMPClauseKind) {
3568                     auto MI = MapExprComponents.rbegin();
3569                     auto ME = MapExprComponents.rend();
3570                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3571                   })) {
3572             VarsWithInheritedDSA[VD] = E;
3573             return;
3574           }
3575         }
3576       }
3577       if (SemaRef.getLangOpts().OpenMP > 50) {
3578         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3579                                  OMPC_DEFAULTMAP_MODIFIER_present;
3580         if (IsModifierPresent) {
3581           if (llvm::find(ImplicitMapModifier[ClauseKind],
3582                          OMPC_MAP_MODIFIER_present) ==
3583               std::end(ImplicitMapModifier[ClauseKind])) {
3584             ImplicitMapModifier[ClauseKind].push_back(
3585                 OMPC_MAP_MODIFIER_present);
3586           }
3587         }
3588       }
3589 
3590       if (isOpenMPTargetExecutionDirective(DKind) &&
3591           !Stack->isLoopControlVariable(VD).first) {
3592         if (!Stack->checkMappableExprComponentListsForDecl(
3593                 VD, /*CurrentRegionOnly=*/true,
3594                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3595                            StackComponents,
3596                        OpenMPClauseKind) {
3597                   if (SemaRef.LangOpts.OpenMP >= 50)
3598                     return !StackComponents.empty();
3599                   // Variable is used if it has been marked as an array, array
3600                   // section, array shaping or the variable iself.
3601                   return StackComponents.size() == 1 ||
3602                          std::all_of(
3603                              std::next(StackComponents.rbegin()),
3604                              StackComponents.rend(),
3605                              [](const OMPClauseMappableExprCommon::
3606                                     MappableComponent &MC) {
3607                                return MC.getAssociatedDeclaration() ==
3608                                           nullptr &&
3609                                       (isa<OMPArraySectionExpr>(
3610                                            MC.getAssociatedExpression()) ||
3611                                        isa<OMPArrayShapingExpr>(
3612                                            MC.getAssociatedExpression()) ||
3613                                        isa<ArraySubscriptExpr>(
3614                                            MC.getAssociatedExpression()));
3615                              });
3616                 })) {
3617           bool IsFirstprivate = false;
3618           // By default lambdas are captured as firstprivates.
3619           if (const auto *RD =
3620                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3621             IsFirstprivate = RD->isLambda();
3622           IsFirstprivate =
3623               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3624           if (IsFirstprivate) {
3625             ImplicitFirstprivate.emplace_back(E);
3626           } else {
3627             OpenMPDefaultmapClauseModifier M =
3628                 Stack->getDefaultmapModifier(ClauseKind);
3629             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3630                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3631             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3632           }
3633           return;
3634         }
3635       }
3636 
3637       // OpenMP [2.9.3.6, Restrictions, p.2]
3638       //  A list item that appears in a reduction clause of the innermost
3639       //  enclosing worksharing or parallel construct may not be accessed in an
3640       //  explicit task.
3641       DVar = Stack->hasInnermostDSA(
3642           VD,
3643           [](OpenMPClauseKind C, bool AppliedToPointee) {
3644             return C == OMPC_reduction && !AppliedToPointee;
3645           },
3646           [](OpenMPDirectiveKind K) {
3647             return isOpenMPParallelDirective(K) ||
3648                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3649           },
3650           /*FromParent=*/true);
3651       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3652         ErrorFound = true;
3653         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3654         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3655         return;
3656       }
3657 
3658       // Define implicit data-sharing attributes for task.
3659       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3660       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3661            (Stack->getDefaultDSA() == DSA_firstprivate &&
3662             DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3663           !Stack->isLoopControlVariable(VD).first) {
3664         ImplicitFirstprivate.push_back(E);
3665         return;
3666       }
3667 
3668       // Store implicitly used globals with declare target link for parent
3669       // target.
3670       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3671           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3672         Stack->addToParentTargetRegionLinkGlobals(E);
3673         return;
3674       }
3675     }
3676   }
VisitMemberExpr(MemberExpr * E)3677   void VisitMemberExpr(MemberExpr *E) {
3678     if (E->isTypeDependent() || E->isValueDependent() ||
3679         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3680       return;
3681     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3682     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3683     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3684       if (!FD)
3685         return;
3686       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3687       // Check if the variable has explicit DSA set and stop analysis if it
3688       // so.
3689       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3690         return;
3691 
3692       if (isOpenMPTargetExecutionDirective(DKind) &&
3693           !Stack->isLoopControlVariable(FD).first &&
3694           !Stack->checkMappableExprComponentListsForDecl(
3695               FD, /*CurrentRegionOnly=*/true,
3696               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3697                      StackComponents,
3698                  OpenMPClauseKind) {
3699                 return isa<CXXThisExpr>(
3700                     cast<MemberExpr>(
3701                         StackComponents.back().getAssociatedExpression())
3702                         ->getBase()
3703                         ->IgnoreParens());
3704               })) {
3705         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3706         //  A bit-field cannot appear in a map clause.
3707         //
3708         if (FD->isBitField())
3709           return;
3710 
3711         // Check to see if the member expression is referencing a class that
3712         // has already been explicitly mapped
3713         if (Stack->isClassPreviouslyMapped(TE->getType()))
3714           return;
3715 
3716         OpenMPDefaultmapClauseModifier Modifier =
3717             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3718         OpenMPDefaultmapClauseKind ClauseKind =
3719             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3720         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3721             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3722         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3723         return;
3724       }
3725 
3726       SourceLocation ELoc = E->getExprLoc();
3727       // OpenMP [2.9.3.6, Restrictions, p.2]
3728       //  A list item that appears in a reduction clause of the innermost
3729       //  enclosing worksharing or parallel construct may not be accessed in
3730       //  an  explicit task.
3731       DVar = Stack->hasInnermostDSA(
3732           FD,
3733           [](OpenMPClauseKind C, bool AppliedToPointee) {
3734             return C == OMPC_reduction && !AppliedToPointee;
3735           },
3736           [](OpenMPDirectiveKind K) {
3737             return isOpenMPParallelDirective(K) ||
3738                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3739           },
3740           /*FromParent=*/true);
3741       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3742         ErrorFound = true;
3743         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3744         reportOriginalDsa(SemaRef, Stack, FD, DVar);
3745         return;
3746       }
3747 
3748       // Define implicit data-sharing attributes for task.
3749       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3750       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3751           !Stack->isLoopControlVariable(FD).first) {
3752         // Check if there is a captured expression for the current field in the
3753         // region. Do not mark it as firstprivate unless there is no captured
3754         // expression.
3755         // TODO: try to make it firstprivate.
3756         if (DVar.CKind != OMPC_unknown)
3757           ImplicitFirstprivate.push_back(E);
3758       }
3759       return;
3760     }
3761     if (isOpenMPTargetExecutionDirective(DKind)) {
3762       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3763       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3764                                         Stack->getCurrentDirective(),
3765                                         /*NoDiagnose=*/true))
3766         return;
3767       const auto *VD = cast<ValueDecl>(
3768           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3769       if (!Stack->checkMappableExprComponentListsForDecl(
3770               VD, /*CurrentRegionOnly=*/true,
3771               [&CurComponents](
3772                   OMPClauseMappableExprCommon::MappableExprComponentListRef
3773                       StackComponents,
3774                   OpenMPClauseKind) {
3775                 auto CCI = CurComponents.rbegin();
3776                 auto CCE = CurComponents.rend();
3777                 for (const auto &SC : llvm::reverse(StackComponents)) {
3778                   // Do both expressions have the same kind?
3779                   if (CCI->getAssociatedExpression()->getStmtClass() !=
3780                       SC.getAssociatedExpression()->getStmtClass())
3781                     if (!((isa<OMPArraySectionExpr>(
3782                                SC.getAssociatedExpression()) ||
3783                            isa<OMPArrayShapingExpr>(
3784                                SC.getAssociatedExpression())) &&
3785                           isa<ArraySubscriptExpr>(
3786                               CCI->getAssociatedExpression())))
3787                       return false;
3788 
3789                   const Decl *CCD = CCI->getAssociatedDeclaration();
3790                   const Decl *SCD = SC.getAssociatedDeclaration();
3791                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3792                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3793                   if (SCD != CCD)
3794                     return false;
3795                   std::advance(CCI, 1);
3796                   if (CCI == CCE)
3797                     break;
3798                 }
3799                 return true;
3800               })) {
3801         Visit(E->getBase());
3802       }
3803     } else if (!TryCaptureCXXThisMembers) {
3804       Visit(E->getBase());
3805     }
3806   }
VisitOMPExecutableDirective(OMPExecutableDirective * S)3807   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3808     for (OMPClause *C : S->clauses()) {
3809       // Skip analysis of arguments of implicitly defined firstprivate clause
3810       // for task|target directives.
3811       // Skip analysis of arguments of implicitly defined map clause for target
3812       // directives.
3813       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3814                  C->isImplicit() &&
3815                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3816         for (Stmt *CC : C->children()) {
3817           if (CC)
3818             Visit(CC);
3819         }
3820       }
3821     }
3822     // Check implicitly captured variables.
3823     VisitSubCaptures(S);
3824   }
3825 
VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective * S)3826   void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
3827     // Loop transformation directives do not introduce data sharing
3828     VisitStmt(S);
3829   }
3830 
VisitStmt(Stmt * S)3831   void VisitStmt(Stmt *S) {
3832     for (Stmt *C : S->children()) {
3833       if (C) {
3834         // Check implicitly captured variables in the task-based directives to
3835         // check if they must be firstprivatized.
3836         Visit(C);
3837       }
3838     }
3839   }
3840 
visitSubCaptures(CapturedStmt * S)3841   void visitSubCaptures(CapturedStmt *S) {
3842     for (const CapturedStmt::Capture &Cap : S->captures()) {
3843       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3844         continue;
3845       VarDecl *VD = Cap.getCapturedVar();
3846       // Do not try to map the variable if it or its sub-component was mapped
3847       // already.
3848       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3849           Stack->checkMappableExprComponentListsForDecl(
3850               VD, /*CurrentRegionOnly=*/true,
3851               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3852                  OpenMPClauseKind) { return true; }))
3853         continue;
3854       DeclRefExpr *DRE = buildDeclRefExpr(
3855           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3856           Cap.getLocation(), /*RefersToCapture=*/true);
3857       Visit(DRE);
3858     }
3859   }
isErrorFound() const3860   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3861   ArrayRef<Expr *> getImplicitFirstprivate() const {
3862     return ImplicitFirstprivate;
3863   }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const3864   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3865                                   OpenMPMapClauseKind MK) const {
3866     return ImplicitMap[DK][MK];
3867   }
3868   ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const3869   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3870     return ImplicitMapModifier[Kind];
3871   }
getVarsWithInheritedDSA() const3872   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3873     return VarsWithInheritedDSA;
3874   }
3875 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3876   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3877       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3878     // Process declare target link variables for the target directives.
3879     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3880       for (DeclRefExpr *E : Stack->getLinkGlobals())
3881         Visit(E);
3882     }
3883   }
3884 };
3885 } // namespace
3886 
handleDeclareVariantConstructTrait(DSAStackTy * Stack,OpenMPDirectiveKind DKind,bool ScopeEntry)3887 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
3888                                                OpenMPDirectiveKind DKind,
3889                                                bool ScopeEntry) {
3890   SmallVector<llvm::omp::TraitProperty, 8> Traits;
3891   if (isOpenMPTargetExecutionDirective(DKind))
3892     Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
3893   if (isOpenMPTeamsDirective(DKind))
3894     Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
3895   if (isOpenMPParallelDirective(DKind))
3896     Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
3897   if (isOpenMPWorksharingDirective(DKind))
3898     Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
3899   if (isOpenMPSimdDirective(DKind))
3900     Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
3901   Stack->handleConstructTrait(Traits, ScopeEntry);
3902 }
3903 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3904 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3905   switch (DKind) {
3906   case OMPD_parallel:
3907   case OMPD_parallel_for:
3908   case OMPD_parallel_for_simd:
3909   case OMPD_parallel_sections:
3910   case OMPD_parallel_master:
3911   case OMPD_teams:
3912   case OMPD_teams_distribute:
3913   case OMPD_teams_distribute_simd: {
3914     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3915     QualType KmpInt32PtrTy =
3916         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3917     Sema::CapturedParamNameType Params[] = {
3918         std::make_pair(".global_tid.", KmpInt32PtrTy),
3919         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3920         std::make_pair(StringRef(), QualType()) // __context with shared vars
3921     };
3922     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3923                              Params);
3924     break;
3925   }
3926   case OMPD_target_teams:
3927   case OMPD_target_parallel:
3928   case OMPD_target_parallel_for:
3929   case OMPD_target_parallel_for_simd:
3930   case OMPD_target_teams_distribute:
3931   case OMPD_target_teams_distribute_simd: {
3932     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3933     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3934     QualType KmpInt32PtrTy =
3935         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3936     QualType Args[] = {VoidPtrTy};
3937     FunctionProtoType::ExtProtoInfo EPI;
3938     EPI.Variadic = true;
3939     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3940     Sema::CapturedParamNameType Params[] = {
3941         std::make_pair(".global_tid.", KmpInt32Ty),
3942         std::make_pair(".part_id.", KmpInt32PtrTy),
3943         std::make_pair(".privates.", VoidPtrTy),
3944         std::make_pair(
3945             ".copy_fn.",
3946             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3947         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3948         std::make_pair(StringRef(), QualType()) // __context with shared vars
3949     };
3950     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3951                              Params, /*OpenMPCaptureLevel=*/0);
3952     // Mark this captured region as inlined, because we don't use outlined
3953     // function directly.
3954     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3955         AlwaysInlineAttr::CreateImplicit(
3956             Context, {}, AttributeCommonInfo::AS_Keyword,
3957             AlwaysInlineAttr::Keyword_forceinline));
3958     Sema::CapturedParamNameType ParamsTarget[] = {
3959         std::make_pair(StringRef(), QualType()) // __context with shared vars
3960     };
3961     // Start a captured region for 'target' with no implicit parameters.
3962     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3963                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
3964     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3965         std::make_pair(".global_tid.", KmpInt32PtrTy),
3966         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3967         std::make_pair(StringRef(), QualType()) // __context with shared vars
3968     };
3969     // Start a captured region for 'teams' or 'parallel'.  Both regions have
3970     // the same implicit parameters.
3971     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3972                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3973     break;
3974   }
3975   case OMPD_target:
3976   case OMPD_target_simd: {
3977     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3978     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3979     QualType KmpInt32PtrTy =
3980         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3981     QualType Args[] = {VoidPtrTy};
3982     FunctionProtoType::ExtProtoInfo EPI;
3983     EPI.Variadic = true;
3984     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3985     Sema::CapturedParamNameType Params[] = {
3986         std::make_pair(".global_tid.", KmpInt32Ty),
3987         std::make_pair(".part_id.", KmpInt32PtrTy),
3988         std::make_pair(".privates.", VoidPtrTy),
3989         std::make_pair(
3990             ".copy_fn.",
3991             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3992         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3993         std::make_pair(StringRef(), QualType()) // __context with shared vars
3994     };
3995     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3996                              Params, /*OpenMPCaptureLevel=*/0);
3997     // Mark this captured region as inlined, because we don't use outlined
3998     // function directly.
3999     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4000         AlwaysInlineAttr::CreateImplicit(
4001             Context, {}, AttributeCommonInfo::AS_Keyword,
4002             AlwaysInlineAttr::Keyword_forceinline));
4003     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4004                              std::make_pair(StringRef(), QualType()),
4005                              /*OpenMPCaptureLevel=*/1);
4006     break;
4007   }
4008   case OMPD_atomic:
4009   case OMPD_critical:
4010   case OMPD_section:
4011   case OMPD_master:
4012   case OMPD_masked:
4013   case OMPD_tile:
4014   case OMPD_unroll:
4015     break;
4016   case OMPD_simd:
4017   case OMPD_for:
4018   case OMPD_for_simd:
4019   case OMPD_sections:
4020   case OMPD_single:
4021   case OMPD_taskgroup:
4022   case OMPD_distribute:
4023   case OMPD_distribute_simd:
4024   case OMPD_ordered:
4025   case OMPD_target_data:
4026   case OMPD_dispatch: {
4027     Sema::CapturedParamNameType Params[] = {
4028         std::make_pair(StringRef(), QualType()) // __context with shared vars
4029     };
4030     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4031                              Params);
4032     break;
4033   }
4034   case OMPD_task: {
4035     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4036     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4037     QualType KmpInt32PtrTy =
4038         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4039     QualType Args[] = {VoidPtrTy};
4040     FunctionProtoType::ExtProtoInfo EPI;
4041     EPI.Variadic = true;
4042     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4043     Sema::CapturedParamNameType Params[] = {
4044         std::make_pair(".global_tid.", KmpInt32Ty),
4045         std::make_pair(".part_id.", KmpInt32PtrTy),
4046         std::make_pair(".privates.", VoidPtrTy),
4047         std::make_pair(
4048             ".copy_fn.",
4049             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4050         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4051         std::make_pair(StringRef(), QualType()) // __context with shared vars
4052     };
4053     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4054                              Params);
4055     // Mark this captured region as inlined, because we don't use outlined
4056     // function directly.
4057     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4058         AlwaysInlineAttr::CreateImplicit(
4059             Context, {}, AttributeCommonInfo::AS_Keyword,
4060             AlwaysInlineAttr::Keyword_forceinline));
4061     break;
4062   }
4063   case OMPD_taskloop:
4064   case OMPD_taskloop_simd:
4065   case OMPD_master_taskloop:
4066   case OMPD_master_taskloop_simd: {
4067     QualType KmpInt32Ty =
4068         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4069             .withConst();
4070     QualType KmpUInt64Ty =
4071         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4072             .withConst();
4073     QualType KmpInt64Ty =
4074         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4075             .withConst();
4076     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4077     QualType KmpInt32PtrTy =
4078         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4079     QualType Args[] = {VoidPtrTy};
4080     FunctionProtoType::ExtProtoInfo EPI;
4081     EPI.Variadic = true;
4082     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4083     Sema::CapturedParamNameType Params[] = {
4084         std::make_pair(".global_tid.", KmpInt32Ty),
4085         std::make_pair(".part_id.", KmpInt32PtrTy),
4086         std::make_pair(".privates.", VoidPtrTy),
4087         std::make_pair(
4088             ".copy_fn.",
4089             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4090         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4091         std::make_pair(".lb.", KmpUInt64Ty),
4092         std::make_pair(".ub.", KmpUInt64Ty),
4093         std::make_pair(".st.", KmpInt64Ty),
4094         std::make_pair(".liter.", KmpInt32Ty),
4095         std::make_pair(".reductions.", VoidPtrTy),
4096         std::make_pair(StringRef(), QualType()) // __context with shared vars
4097     };
4098     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4099                              Params);
4100     // Mark this captured region as inlined, because we don't use outlined
4101     // function directly.
4102     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4103         AlwaysInlineAttr::CreateImplicit(
4104             Context, {}, AttributeCommonInfo::AS_Keyword,
4105             AlwaysInlineAttr::Keyword_forceinline));
4106     break;
4107   }
4108   case OMPD_parallel_master_taskloop:
4109   case OMPD_parallel_master_taskloop_simd: {
4110     QualType KmpInt32Ty =
4111         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4112             .withConst();
4113     QualType KmpUInt64Ty =
4114         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4115             .withConst();
4116     QualType KmpInt64Ty =
4117         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4118             .withConst();
4119     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4120     QualType KmpInt32PtrTy =
4121         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4122     Sema::CapturedParamNameType ParamsParallel[] = {
4123         std::make_pair(".global_tid.", KmpInt32PtrTy),
4124         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4125         std::make_pair(StringRef(), QualType()) // __context with shared vars
4126     };
4127     // Start a captured region for 'parallel'.
4128     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4129                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4130     QualType Args[] = {VoidPtrTy};
4131     FunctionProtoType::ExtProtoInfo EPI;
4132     EPI.Variadic = true;
4133     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4134     Sema::CapturedParamNameType Params[] = {
4135         std::make_pair(".global_tid.", KmpInt32Ty),
4136         std::make_pair(".part_id.", KmpInt32PtrTy),
4137         std::make_pair(".privates.", VoidPtrTy),
4138         std::make_pair(
4139             ".copy_fn.",
4140             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4141         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4142         std::make_pair(".lb.", KmpUInt64Ty),
4143         std::make_pair(".ub.", KmpUInt64Ty),
4144         std::make_pair(".st.", KmpInt64Ty),
4145         std::make_pair(".liter.", KmpInt32Ty),
4146         std::make_pair(".reductions.", VoidPtrTy),
4147         std::make_pair(StringRef(), QualType()) // __context with shared vars
4148     };
4149     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4150                              Params, /*OpenMPCaptureLevel=*/1);
4151     // Mark this captured region as inlined, because we don't use outlined
4152     // function directly.
4153     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4154         AlwaysInlineAttr::CreateImplicit(
4155             Context, {}, AttributeCommonInfo::AS_Keyword,
4156             AlwaysInlineAttr::Keyword_forceinline));
4157     break;
4158   }
4159   case OMPD_distribute_parallel_for_simd:
4160   case OMPD_distribute_parallel_for: {
4161     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4162     QualType KmpInt32PtrTy =
4163         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4164     Sema::CapturedParamNameType Params[] = {
4165         std::make_pair(".global_tid.", KmpInt32PtrTy),
4166         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4167         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4168         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4169         std::make_pair(StringRef(), QualType()) // __context with shared vars
4170     };
4171     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4172                              Params);
4173     break;
4174   }
4175   case OMPD_target_teams_distribute_parallel_for:
4176   case OMPD_target_teams_distribute_parallel_for_simd: {
4177     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4178     QualType KmpInt32PtrTy =
4179         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4180     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4181 
4182     QualType Args[] = {VoidPtrTy};
4183     FunctionProtoType::ExtProtoInfo EPI;
4184     EPI.Variadic = true;
4185     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4186     Sema::CapturedParamNameType Params[] = {
4187         std::make_pair(".global_tid.", KmpInt32Ty),
4188         std::make_pair(".part_id.", KmpInt32PtrTy),
4189         std::make_pair(".privates.", VoidPtrTy),
4190         std::make_pair(
4191             ".copy_fn.",
4192             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4193         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4194         std::make_pair(StringRef(), QualType()) // __context with shared vars
4195     };
4196     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4197                              Params, /*OpenMPCaptureLevel=*/0);
4198     // Mark this captured region as inlined, because we don't use outlined
4199     // function directly.
4200     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4201         AlwaysInlineAttr::CreateImplicit(
4202             Context, {}, AttributeCommonInfo::AS_Keyword,
4203             AlwaysInlineAttr::Keyword_forceinline));
4204     Sema::CapturedParamNameType ParamsTarget[] = {
4205         std::make_pair(StringRef(), QualType()) // __context with shared vars
4206     };
4207     // Start a captured region for 'target' with no implicit parameters.
4208     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4209                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4210 
4211     Sema::CapturedParamNameType ParamsTeams[] = {
4212         std::make_pair(".global_tid.", KmpInt32PtrTy),
4213         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4214         std::make_pair(StringRef(), QualType()) // __context with shared vars
4215     };
4216     // Start a captured region for 'target' with no implicit parameters.
4217     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4218                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4219 
4220     Sema::CapturedParamNameType ParamsParallel[] = {
4221         std::make_pair(".global_tid.", KmpInt32PtrTy),
4222         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4223         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4224         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4225         std::make_pair(StringRef(), QualType()) // __context with shared vars
4226     };
4227     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4228     // the same implicit parameters.
4229     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4230                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4231     break;
4232   }
4233 
4234   case OMPD_teams_distribute_parallel_for:
4235   case OMPD_teams_distribute_parallel_for_simd: {
4236     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4237     QualType KmpInt32PtrTy =
4238         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4239 
4240     Sema::CapturedParamNameType ParamsTeams[] = {
4241         std::make_pair(".global_tid.", KmpInt32PtrTy),
4242         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4243         std::make_pair(StringRef(), QualType()) // __context with shared vars
4244     };
4245     // Start a captured region for 'target' with no implicit parameters.
4246     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4247                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4248 
4249     Sema::CapturedParamNameType ParamsParallel[] = {
4250         std::make_pair(".global_tid.", KmpInt32PtrTy),
4251         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4252         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4253         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4254         std::make_pair(StringRef(), QualType()) // __context with shared vars
4255     };
4256     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4257     // the same implicit parameters.
4258     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4259                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4260     break;
4261   }
4262   case OMPD_target_update:
4263   case OMPD_target_enter_data:
4264   case OMPD_target_exit_data: {
4265     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4266     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4267     QualType KmpInt32PtrTy =
4268         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4269     QualType Args[] = {VoidPtrTy};
4270     FunctionProtoType::ExtProtoInfo EPI;
4271     EPI.Variadic = true;
4272     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4273     Sema::CapturedParamNameType Params[] = {
4274         std::make_pair(".global_tid.", KmpInt32Ty),
4275         std::make_pair(".part_id.", KmpInt32PtrTy),
4276         std::make_pair(".privates.", VoidPtrTy),
4277         std::make_pair(
4278             ".copy_fn.",
4279             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4280         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4281         std::make_pair(StringRef(), QualType()) // __context with shared vars
4282     };
4283     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4284                              Params);
4285     // Mark this captured region as inlined, because we don't use outlined
4286     // function directly.
4287     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4288         AlwaysInlineAttr::CreateImplicit(
4289             Context, {}, AttributeCommonInfo::AS_Keyword,
4290             AlwaysInlineAttr::Keyword_forceinline));
4291     break;
4292   }
4293   case OMPD_threadprivate:
4294   case OMPD_allocate:
4295   case OMPD_taskyield:
4296   case OMPD_barrier:
4297   case OMPD_taskwait:
4298   case OMPD_cancellation_point:
4299   case OMPD_cancel:
4300   case OMPD_flush:
4301   case OMPD_depobj:
4302   case OMPD_scan:
4303   case OMPD_declare_reduction:
4304   case OMPD_declare_mapper:
4305   case OMPD_declare_simd:
4306   case OMPD_declare_target:
4307   case OMPD_end_declare_target:
4308   case OMPD_requires:
4309   case OMPD_declare_variant:
4310   case OMPD_begin_declare_variant:
4311   case OMPD_end_declare_variant:
4312   case OMPD_metadirective:
4313     llvm_unreachable("OpenMP Directive is not allowed");
4314   case OMPD_unknown:
4315   default:
4316     llvm_unreachable("Unknown OpenMP directive");
4317   }
4318   DSAStack->setContext(CurContext);
4319   handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4320 }
4321 
getNumberOfConstructScopes(unsigned Level) const4322 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4323   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4324 }
4325 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4326 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4327   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4328   getOpenMPCaptureRegions(CaptureRegions, DKind);
4329   return CaptureRegions.size();
4330 }
4331 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4332 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4333                                              Expr *CaptureExpr, bool WithInit,
4334                                              bool AsExpression) {
4335   assert(CaptureExpr);
4336   ASTContext &C = S.getASTContext();
4337   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4338   QualType Ty = Init->getType();
4339   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4340     if (S.getLangOpts().CPlusPlus) {
4341       Ty = C.getLValueReferenceType(Ty);
4342     } else {
4343       Ty = C.getPointerType(Ty);
4344       ExprResult Res =
4345           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4346       if (!Res.isUsable())
4347         return nullptr;
4348       Init = Res.get();
4349     }
4350     WithInit = true;
4351   }
4352   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4353                                           CaptureExpr->getBeginLoc());
4354   if (!WithInit)
4355     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4356   S.CurContext->addHiddenDecl(CED);
4357   Sema::TentativeAnalysisScope Trap(S);
4358   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4359   return CED;
4360 }
4361 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4362 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4363                                  bool WithInit) {
4364   OMPCapturedExprDecl *CD;
4365   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4366     CD = cast<OMPCapturedExprDecl>(VD);
4367   else
4368     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4369                           /*AsExpression=*/false);
4370   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4371                           CaptureExpr->getExprLoc());
4372 }
4373 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4374 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4375   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4376   if (!Ref) {
4377     OMPCapturedExprDecl *CD = buildCaptureDecl(
4378         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4379         /*WithInit=*/true, /*AsExpression=*/true);
4380     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4381                            CaptureExpr->getExprLoc());
4382   }
4383   ExprResult Res = Ref;
4384   if (!S.getLangOpts().CPlusPlus &&
4385       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4386       Ref->getType()->isPointerType()) {
4387     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4388     if (!Res.isUsable())
4389       return ExprError();
4390   }
4391   return S.DefaultLvalueConversion(Res.get());
4392 }
4393 
4394 namespace {
4395 // OpenMP directives parsed in this section are represented as a
4396 // CapturedStatement with an associated statement.  If a syntax error
4397 // is detected during the parsing of the associated statement, the
4398 // compiler must abort processing and close the CapturedStatement.
4399 //
4400 // Combined directives such as 'target parallel' have more than one
4401 // nested CapturedStatements.  This RAII ensures that we unwind out
4402 // of all the nested CapturedStatements when an error is found.
4403 class CaptureRegionUnwinderRAII {
4404 private:
4405   Sema &S;
4406   bool &ErrorFound;
4407   OpenMPDirectiveKind DKind = OMPD_unknown;
4408 
4409 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4410   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4411                             OpenMPDirectiveKind DKind)
4412       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4413   ~CaptureRegionUnwinderRAII() {
4414     if (ErrorFound) {
4415       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4416       while (--ThisCaptureLevel >= 0)
4417         S.ActOnCapturedRegionError();
4418     }
4419   }
4420 };
4421 } // namespace
4422 
tryCaptureOpenMPLambdas(ValueDecl * V)4423 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4424   // Capture variables captured by reference in lambdas for target-based
4425   // directives.
4426   if (!CurContext->isDependentContext() &&
4427       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4428        isOpenMPTargetDataManagementDirective(
4429            DSAStack->getCurrentDirective()))) {
4430     QualType Type = V->getType();
4431     if (const auto *RD = Type.getCanonicalType()
4432                              .getNonReferenceType()
4433                              ->getAsCXXRecordDecl()) {
4434       bool SavedForceCaptureByReferenceInTargetExecutable =
4435           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4436       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4437           /*V=*/true);
4438       if (RD->isLambda()) {
4439         llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4440         FieldDecl *ThisCapture;
4441         RD->getCaptureFields(Captures, ThisCapture);
4442         for (const LambdaCapture &LC : RD->captures()) {
4443           if (LC.getCaptureKind() == LCK_ByRef) {
4444             VarDecl *VD = LC.getCapturedVar();
4445             DeclContext *VDC = VD->getDeclContext();
4446             if (!VDC->Encloses(CurContext))
4447               continue;
4448             MarkVariableReferenced(LC.getLocation(), VD);
4449           } else if (LC.getCaptureKind() == LCK_This) {
4450             QualType ThisTy = getCurrentThisType();
4451             if (!ThisTy.isNull() &&
4452                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4453               CheckCXXThisCapture(LC.getLocation());
4454           }
4455         }
4456       }
4457       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4458           SavedForceCaptureByReferenceInTargetExecutable);
4459     }
4460   }
4461 }
4462 
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4463 static bool checkOrderedOrderSpecified(Sema &S,
4464                                        const ArrayRef<OMPClause *> Clauses) {
4465   const OMPOrderedClause *Ordered = nullptr;
4466   const OMPOrderClause *Order = nullptr;
4467 
4468   for (const OMPClause *Clause : Clauses) {
4469     if (Clause->getClauseKind() == OMPC_ordered)
4470       Ordered = cast<OMPOrderedClause>(Clause);
4471     else if (Clause->getClauseKind() == OMPC_order) {
4472       Order = cast<OMPOrderClause>(Clause);
4473       if (Order->getKind() != OMPC_ORDER_concurrent)
4474         Order = nullptr;
4475     }
4476     if (Ordered && Order)
4477       break;
4478   }
4479 
4480   if (Ordered && Order) {
4481     S.Diag(Order->getKindKwLoc(),
4482            diag::err_omp_simple_clause_incompatible_with_ordered)
4483         << getOpenMPClauseName(OMPC_order)
4484         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4485         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4486     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4487         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4488     return true;
4489   }
4490   return false;
4491 }
4492 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4493 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4494                                       ArrayRef<OMPClause *> Clauses) {
4495   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4496                                      /* ScopeEntry */ false);
4497   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4498       DSAStack->getCurrentDirective() == OMPD_critical ||
4499       DSAStack->getCurrentDirective() == OMPD_section ||
4500       DSAStack->getCurrentDirective() == OMPD_master ||
4501       DSAStack->getCurrentDirective() == OMPD_masked)
4502     return S;
4503 
4504   bool ErrorFound = false;
4505   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4506       *this, ErrorFound, DSAStack->getCurrentDirective());
4507   if (!S.isUsable()) {
4508     ErrorFound = true;
4509     return StmtError();
4510   }
4511 
4512   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4513   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4514   OMPOrderedClause *OC = nullptr;
4515   OMPScheduleClause *SC = nullptr;
4516   SmallVector<const OMPLinearClause *, 4> LCs;
4517   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4518   // This is required for proper codegen.
4519   for (OMPClause *Clause : Clauses) {
4520     if (!LangOpts.OpenMPSimd &&
4521         isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4522         Clause->getClauseKind() == OMPC_in_reduction) {
4523       // Capture taskgroup task_reduction descriptors inside the tasking regions
4524       // with the corresponding in_reduction items.
4525       auto *IRC = cast<OMPInReductionClause>(Clause);
4526       for (Expr *E : IRC->taskgroup_descriptors())
4527         if (E)
4528           MarkDeclarationsReferencedInExpr(E);
4529     }
4530     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4531         Clause->getClauseKind() == OMPC_copyprivate ||
4532         (getLangOpts().OpenMPUseTLS &&
4533          getASTContext().getTargetInfo().isTLSSupported() &&
4534          Clause->getClauseKind() == OMPC_copyin)) {
4535       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4536       // Mark all variables in private list clauses as used in inner region.
4537       for (Stmt *VarRef : Clause->children()) {
4538         if (auto *E = cast_or_null<Expr>(VarRef)) {
4539           MarkDeclarationsReferencedInExpr(E);
4540         }
4541       }
4542       DSAStack->setForceVarCapturing(/*V=*/false);
4543     } else if (isOpenMPLoopTransformationDirective(
4544                    DSAStack->getCurrentDirective())) {
4545       assert(CaptureRegions.empty() &&
4546              "No captured regions in loop transformation directives.");
4547     } else if (CaptureRegions.size() > 1 ||
4548                CaptureRegions.back() != OMPD_unknown) {
4549       if (auto *C = OMPClauseWithPreInit::get(Clause))
4550         PICs.push_back(C);
4551       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4552         if (Expr *E = C->getPostUpdateExpr())
4553           MarkDeclarationsReferencedInExpr(E);
4554       }
4555     }
4556     if (Clause->getClauseKind() == OMPC_schedule)
4557       SC = cast<OMPScheduleClause>(Clause);
4558     else if (Clause->getClauseKind() == OMPC_ordered)
4559       OC = cast<OMPOrderedClause>(Clause);
4560     else if (Clause->getClauseKind() == OMPC_linear)
4561       LCs.push_back(cast<OMPLinearClause>(Clause));
4562   }
4563   // Capture allocator expressions if used.
4564   for (Expr *E : DSAStack->getInnerAllocators())
4565     MarkDeclarationsReferencedInExpr(E);
4566   // OpenMP, 2.7.1 Loop Construct, Restrictions
4567   // The nonmonotonic modifier cannot be specified if an ordered clause is
4568   // specified.
4569   if (SC &&
4570       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4571        SC->getSecondScheduleModifier() ==
4572            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4573       OC) {
4574     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4575              ? SC->getFirstScheduleModifierLoc()
4576              : SC->getSecondScheduleModifierLoc(),
4577          diag::err_omp_simple_clause_incompatible_with_ordered)
4578         << getOpenMPClauseName(OMPC_schedule)
4579         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4580                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4581         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4582     ErrorFound = true;
4583   }
4584   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4585   // If an order(concurrent) clause is present, an ordered clause may not appear
4586   // on the same directive.
4587   if (checkOrderedOrderSpecified(*this, Clauses))
4588     ErrorFound = true;
4589   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4590     for (const OMPLinearClause *C : LCs) {
4591       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4592           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4593     }
4594     ErrorFound = true;
4595   }
4596   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4597       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4598       OC->getNumForLoops()) {
4599     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4600         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4601     ErrorFound = true;
4602   }
4603   if (ErrorFound) {
4604     return StmtError();
4605   }
4606   StmtResult SR = S;
4607   unsigned CompletedRegions = 0;
4608   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4609     // Mark all variables in private list clauses as used in inner region.
4610     // Required for proper codegen of combined directives.
4611     // TODO: add processing for other clauses.
4612     if (ThisCaptureRegion != OMPD_unknown) {
4613       for (const clang::OMPClauseWithPreInit *C : PICs) {
4614         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4615         // Find the particular capture region for the clause if the
4616         // directive is a combined one with multiple capture regions.
4617         // If the directive is not a combined one, the capture region
4618         // associated with the clause is OMPD_unknown and is generated
4619         // only once.
4620         if (CaptureRegion == ThisCaptureRegion ||
4621             CaptureRegion == OMPD_unknown) {
4622           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4623             for (Decl *D : DS->decls())
4624               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4625           }
4626         }
4627       }
4628     }
4629     if (ThisCaptureRegion == OMPD_target) {
4630       // Capture allocator traits in the target region. They are used implicitly
4631       // and, thus, are not captured by default.
4632       for (OMPClause *C : Clauses) {
4633         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4634           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4635                ++I) {
4636             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4637             if (Expr *E = D.AllocatorTraits)
4638               MarkDeclarationsReferencedInExpr(E);
4639           }
4640           continue;
4641         }
4642       }
4643     }
4644     if (ThisCaptureRegion == OMPD_parallel) {
4645       // Capture temp arrays for inscan reductions and locals in aligned
4646       // clauses.
4647       for (OMPClause *C : Clauses) {
4648         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4649           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4650             continue;
4651           for (Expr *E : RC->copy_array_temps())
4652             MarkDeclarationsReferencedInExpr(E);
4653         }
4654         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4655           for (Expr *E : AC->varlists())
4656             MarkDeclarationsReferencedInExpr(E);
4657         }
4658       }
4659     }
4660     if (++CompletedRegions == CaptureRegions.size())
4661       DSAStack->setBodyComplete();
4662     SR = ActOnCapturedRegionEnd(SR.get());
4663   }
4664   return SR;
4665 }
4666 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4667 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4668                               OpenMPDirectiveKind CancelRegion,
4669                               SourceLocation StartLoc) {
4670   // CancelRegion is only needed for cancel and cancellation_point.
4671   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4672     return false;
4673 
4674   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4675       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4676     return false;
4677 
4678   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4679       << getOpenMPDirectiveName(CancelRegion);
4680   return true;
4681 }
4682 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4683 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4684                                   OpenMPDirectiveKind CurrentRegion,
4685                                   const DeclarationNameInfo &CurrentName,
4686                                   OpenMPDirectiveKind CancelRegion,
4687                                   SourceLocation StartLoc) {
4688   if (Stack->getCurScope()) {
4689     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4690     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4691     bool NestingProhibited = false;
4692     bool CloseNesting = true;
4693     bool OrphanSeen = false;
4694     enum {
4695       NoRecommend,
4696       ShouldBeInParallelRegion,
4697       ShouldBeInOrderedRegion,
4698       ShouldBeInTargetRegion,
4699       ShouldBeInTeamsRegion,
4700       ShouldBeInLoopSimdRegion,
4701     } Recommend = NoRecommend;
4702     if (isOpenMPSimdDirective(ParentRegion) &&
4703         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4704          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4705           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4706           CurrentRegion != OMPD_scan))) {
4707       // OpenMP [2.16, Nesting of Regions]
4708       // OpenMP constructs may not be nested inside a simd region.
4709       // OpenMP [2.8.1,simd Construct, Restrictions]
4710       // An ordered construct with the simd clause is the only OpenMP
4711       // construct that can appear in the simd region.
4712       // Allowing a SIMD construct nested in another SIMD construct is an
4713       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4714       // message.
4715       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4716       // The only OpenMP constructs that can be encountered during execution of
4717       // a simd region are the atomic construct, the loop construct, the simd
4718       // construct and the ordered construct with the simd clause.
4719       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4720                                  ? diag::err_omp_prohibited_region_simd
4721                                  : diag::warn_omp_nesting_simd)
4722           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4723       return CurrentRegion != OMPD_simd;
4724     }
4725     if (ParentRegion == OMPD_atomic) {
4726       // OpenMP [2.16, Nesting of Regions]
4727       // OpenMP constructs may not be nested inside an atomic region.
4728       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4729       return true;
4730     }
4731     if (CurrentRegion == OMPD_section) {
4732       // OpenMP [2.7.2, sections Construct, Restrictions]
4733       // Orphaned section directives are prohibited. That is, the section
4734       // directives must appear within the sections construct and must not be
4735       // encountered elsewhere in the sections region.
4736       if (ParentRegion != OMPD_sections &&
4737           ParentRegion != OMPD_parallel_sections) {
4738         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4739             << (ParentRegion != OMPD_unknown)
4740             << getOpenMPDirectiveName(ParentRegion);
4741         return true;
4742       }
4743       return false;
4744     }
4745     // Allow some constructs (except teams and cancellation constructs) to be
4746     // orphaned (they could be used in functions, called from OpenMP regions
4747     // with the required preconditions).
4748     if (ParentRegion == OMPD_unknown &&
4749         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4750         CurrentRegion != OMPD_cancellation_point &&
4751         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4752       return false;
4753     if (CurrentRegion == OMPD_cancellation_point ||
4754         CurrentRegion == OMPD_cancel) {
4755       // OpenMP [2.16, Nesting of Regions]
4756       // A cancellation point construct for which construct-type-clause is
4757       // taskgroup must be nested inside a task construct. A cancellation
4758       // point construct for which construct-type-clause is not taskgroup must
4759       // be closely nested inside an OpenMP construct that matches the type
4760       // specified in construct-type-clause.
4761       // A cancel construct for which construct-type-clause is taskgroup must be
4762       // nested inside a task construct. A cancel construct for which
4763       // construct-type-clause is not taskgroup must be closely nested inside an
4764       // OpenMP construct that matches the type specified in
4765       // construct-type-clause.
4766       NestingProhibited =
4767           !((CancelRegion == OMPD_parallel &&
4768              (ParentRegion == OMPD_parallel ||
4769               ParentRegion == OMPD_target_parallel)) ||
4770             (CancelRegion == OMPD_for &&
4771              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4772               ParentRegion == OMPD_target_parallel_for ||
4773               ParentRegion == OMPD_distribute_parallel_for ||
4774               ParentRegion == OMPD_teams_distribute_parallel_for ||
4775               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4776             (CancelRegion == OMPD_taskgroup &&
4777              (ParentRegion == OMPD_task ||
4778               (SemaRef.getLangOpts().OpenMP >= 50 &&
4779                (ParentRegion == OMPD_taskloop ||
4780                 ParentRegion == OMPD_master_taskloop ||
4781                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4782             (CancelRegion == OMPD_sections &&
4783              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4784               ParentRegion == OMPD_parallel_sections)));
4785       OrphanSeen = ParentRegion == OMPD_unknown;
4786     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4787       // OpenMP 5.1 [2.22, Nesting of Regions]
4788       // A masked region may not be closely nested inside a worksharing, loop,
4789       // atomic, task, or taskloop region.
4790       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4791                           isOpenMPTaskingDirective(ParentRegion);
4792     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4793       // OpenMP [2.16, Nesting of Regions]
4794       // A critical region may not be nested (closely or otherwise) inside a
4795       // critical region with the same name. Note that this restriction is not
4796       // sufficient to prevent deadlock.
4797       SourceLocation PreviousCriticalLoc;
4798       bool DeadLock = Stack->hasDirective(
4799           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4800                                               const DeclarationNameInfo &DNI,
4801                                               SourceLocation Loc) {
4802             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4803               PreviousCriticalLoc = Loc;
4804               return true;
4805             }
4806             return false;
4807           },
4808           false /* skip top directive */);
4809       if (DeadLock) {
4810         SemaRef.Diag(StartLoc,
4811                      diag::err_omp_prohibited_region_critical_same_name)
4812             << CurrentName.getName();
4813         if (PreviousCriticalLoc.isValid())
4814           SemaRef.Diag(PreviousCriticalLoc,
4815                        diag::note_omp_previous_critical_region);
4816         return true;
4817       }
4818     } else if (CurrentRegion == OMPD_barrier) {
4819       // OpenMP 5.1 [2.22, Nesting of Regions]
4820       // A barrier region may not be closely nested inside a worksharing, loop,
4821       // task, taskloop, critical, ordered, atomic, or masked region.
4822       NestingProhibited =
4823           isOpenMPWorksharingDirective(ParentRegion) ||
4824           isOpenMPTaskingDirective(ParentRegion) ||
4825           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4826           ParentRegion == OMPD_parallel_master ||
4827           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4828     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4829                !isOpenMPParallelDirective(CurrentRegion) &&
4830                !isOpenMPTeamsDirective(CurrentRegion)) {
4831       // OpenMP 5.1 [2.22, Nesting of Regions]
4832       // A loop region that binds to a parallel region or a worksharing region
4833       // may not be closely nested inside a worksharing, loop, task, taskloop,
4834       // critical, ordered, atomic, or masked region.
4835       NestingProhibited =
4836           isOpenMPWorksharingDirective(ParentRegion) ||
4837           isOpenMPTaskingDirective(ParentRegion) ||
4838           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4839           ParentRegion == OMPD_parallel_master ||
4840           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4841       Recommend = ShouldBeInParallelRegion;
4842     } else if (CurrentRegion == OMPD_ordered) {
4843       // OpenMP [2.16, Nesting of Regions]
4844       // An ordered region may not be closely nested inside a critical,
4845       // atomic, or explicit task region.
4846       // An ordered region must be closely nested inside a loop region (or
4847       // parallel loop region) with an ordered clause.
4848       // OpenMP [2.8.1,simd Construct, Restrictions]
4849       // An ordered construct with the simd clause is the only OpenMP construct
4850       // that can appear in the simd region.
4851       NestingProhibited = ParentRegion == OMPD_critical ||
4852                           isOpenMPTaskingDirective(ParentRegion) ||
4853                           !(isOpenMPSimdDirective(ParentRegion) ||
4854                             Stack->isParentOrderedRegion());
4855       Recommend = ShouldBeInOrderedRegion;
4856     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4857       // OpenMP [2.16, Nesting of Regions]
4858       // If specified, a teams construct must be contained within a target
4859       // construct.
4860       NestingProhibited =
4861           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4862           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4863            ParentRegion != OMPD_target);
4864       OrphanSeen = ParentRegion == OMPD_unknown;
4865       Recommend = ShouldBeInTargetRegion;
4866     } else if (CurrentRegion == OMPD_scan) {
4867       // OpenMP [2.16, Nesting of Regions]
4868       // If specified, a teams construct must be contained within a target
4869       // construct.
4870       NestingProhibited =
4871           SemaRef.LangOpts.OpenMP < 50 ||
4872           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4873            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4874            ParentRegion != OMPD_parallel_for_simd);
4875       OrphanSeen = ParentRegion == OMPD_unknown;
4876       Recommend = ShouldBeInLoopSimdRegion;
4877     }
4878     if (!NestingProhibited &&
4879         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4880         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4881         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4882       // OpenMP [2.16, Nesting of Regions]
4883       // distribute, parallel, parallel sections, parallel workshare, and the
4884       // parallel loop and parallel loop SIMD constructs are the only OpenMP
4885       // constructs that can be closely nested in the teams region.
4886       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4887                           !isOpenMPDistributeDirective(CurrentRegion);
4888       Recommend = ShouldBeInParallelRegion;
4889     }
4890     if (!NestingProhibited &&
4891         isOpenMPNestingDistributeDirective(CurrentRegion)) {
4892       // OpenMP 4.5 [2.17 Nesting of Regions]
4893       // The region associated with the distribute construct must be strictly
4894       // nested inside a teams region
4895       NestingProhibited =
4896           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4897       Recommend = ShouldBeInTeamsRegion;
4898     }
4899     if (!NestingProhibited &&
4900         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4901          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4902       // OpenMP 4.5 [2.17 Nesting of Regions]
4903       // If a target, target update, target data, target enter data, or
4904       // target exit data construct is encountered during execution of a
4905       // target region, the behavior is unspecified.
4906       NestingProhibited = Stack->hasDirective(
4907           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4908                              SourceLocation) {
4909             if (isOpenMPTargetExecutionDirective(K)) {
4910               OffendingRegion = K;
4911               return true;
4912             }
4913             return false;
4914           },
4915           false /* don't skip top directive */);
4916       CloseNesting = false;
4917     }
4918     if (NestingProhibited) {
4919       if (OrphanSeen) {
4920         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4921             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4922       } else {
4923         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4924             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4925             << Recommend << getOpenMPDirectiveName(CurrentRegion);
4926       }
4927       return true;
4928     }
4929   }
4930   return false;
4931 }
4932 
4933 struct Kind2Unsigned {
4934   using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4935   unsigned operator()(argument_type DK) { return unsigned(DK); }
4936 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4937 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4938                            ArrayRef<OMPClause *> Clauses,
4939                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4940   bool ErrorFound = false;
4941   unsigned NamedModifiersNumber = 0;
4942   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4943   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4944   SmallVector<SourceLocation, 4> NameModifierLoc;
4945   for (const OMPClause *C : Clauses) {
4946     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4947       // At most one if clause without a directive-name-modifier can appear on
4948       // the directive.
4949       OpenMPDirectiveKind CurNM = IC->getNameModifier();
4950       if (FoundNameModifiers[CurNM]) {
4951         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4952             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4953             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4954         ErrorFound = true;
4955       } else if (CurNM != OMPD_unknown) {
4956         NameModifierLoc.push_back(IC->getNameModifierLoc());
4957         ++NamedModifiersNumber;
4958       }
4959       FoundNameModifiers[CurNM] = IC;
4960       if (CurNM == OMPD_unknown)
4961         continue;
4962       // Check if the specified name modifier is allowed for the current
4963       // directive.
4964       // At most one if clause with the particular directive-name-modifier can
4965       // appear on the directive.
4966       bool MatchFound = false;
4967       for (auto NM : AllowedNameModifiers) {
4968         if (CurNM == NM) {
4969           MatchFound = true;
4970           break;
4971         }
4972       }
4973       if (!MatchFound) {
4974         S.Diag(IC->getNameModifierLoc(),
4975                diag::err_omp_wrong_if_directive_name_modifier)
4976             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4977         ErrorFound = true;
4978       }
4979     }
4980   }
4981   // If any if clause on the directive includes a directive-name-modifier then
4982   // all if clauses on the directive must include a directive-name-modifier.
4983   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4984     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4985       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4986              diag::err_omp_no_more_if_clause);
4987     } else {
4988       std::string Values;
4989       std::string Sep(", ");
4990       unsigned AllowedCnt = 0;
4991       unsigned TotalAllowedNum =
4992           AllowedNameModifiers.size() - NamedModifiersNumber;
4993       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4994            ++Cnt) {
4995         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4996         if (!FoundNameModifiers[NM]) {
4997           Values += "'";
4998           Values += getOpenMPDirectiveName(NM);
4999           Values += "'";
5000           if (AllowedCnt + 2 == TotalAllowedNum)
5001             Values += " or ";
5002           else if (AllowedCnt + 1 != TotalAllowedNum)
5003             Values += Sep;
5004           ++AllowedCnt;
5005         }
5006       }
5007       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5008              diag::err_omp_unnamed_if_clause)
5009           << (TotalAllowedNum > 1) << Values;
5010     }
5011     for (SourceLocation Loc : NameModifierLoc) {
5012       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5013     }
5014     ErrorFound = true;
5015   }
5016   return ErrorFound;
5017 }
5018 
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)5019 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5020                                                    SourceLocation &ELoc,
5021                                                    SourceRange &ERange,
5022                                                    bool AllowArraySection) {
5023   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5024       RefExpr->containsUnexpandedParameterPack())
5025     return std::make_pair(nullptr, true);
5026 
5027   // OpenMP [3.1, C/C++]
5028   //  A list item is a variable name.
5029   // OpenMP  [2.9.3.3, Restrictions, p.1]
5030   //  A variable that is part of another variable (as an array or
5031   //  structure element) cannot appear in a private clause.
5032   RefExpr = RefExpr->IgnoreParens();
5033   enum {
5034     NoArrayExpr = -1,
5035     ArraySubscript = 0,
5036     OMPArraySection = 1
5037   } IsArrayExpr = NoArrayExpr;
5038   if (AllowArraySection) {
5039     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5040       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5041       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5042         Base = TempASE->getBase()->IgnoreParenImpCasts();
5043       RefExpr = Base;
5044       IsArrayExpr = ArraySubscript;
5045     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5046       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5047       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5048         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5049       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5050         Base = TempASE->getBase()->IgnoreParenImpCasts();
5051       RefExpr = Base;
5052       IsArrayExpr = OMPArraySection;
5053     }
5054   }
5055   ELoc = RefExpr->getExprLoc();
5056   ERange = RefExpr->getSourceRange();
5057   RefExpr = RefExpr->IgnoreParenImpCasts();
5058   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5059   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5060   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5061       (S.getCurrentThisType().isNull() || !ME ||
5062        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5063        !isa<FieldDecl>(ME->getMemberDecl()))) {
5064     if (IsArrayExpr != NoArrayExpr) {
5065       S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
5066                                                          << ERange;
5067     } else {
5068       S.Diag(ELoc,
5069              AllowArraySection
5070                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5071                  : diag::err_omp_expected_var_name_member_expr)
5072           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5073     }
5074     return std::make_pair(nullptr, false);
5075   }
5076   return std::make_pair(
5077       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5078 }
5079 
5080 namespace {
5081 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5082 /// target regions.
5083 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5084   DSAStackTy *S = nullptr;
5085 
5086 public:
VisitDeclRefExpr(const DeclRefExpr * E)5087   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5088     return S->isUsesAllocatorsDecl(E->getDecl())
5089                .getValueOr(
5090                    DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5091            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5092   }
VisitStmt(const Stmt * S)5093   bool VisitStmt(const Stmt *S) {
5094     for (const Stmt *Child : S->children()) {
5095       if (Child && Visit(Child))
5096         return true;
5097     }
5098     return false;
5099   }
AllocatorChecker(DSAStackTy * S)5100   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5101 };
5102 } // namespace
5103 
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5104 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5105                                  ArrayRef<OMPClause *> Clauses) {
5106   assert(!S.CurContext->isDependentContext() &&
5107          "Expected non-dependent context.");
5108   auto AllocateRange =
5109       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5110   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5111       DeclToCopy;
5112   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5113     return isOpenMPPrivate(C->getClauseKind());
5114   });
5115   for (OMPClause *Cl : PrivateRange) {
5116     MutableArrayRef<Expr *>::iterator I, It, Et;
5117     if (Cl->getClauseKind() == OMPC_private) {
5118       auto *PC = cast<OMPPrivateClause>(Cl);
5119       I = PC->private_copies().begin();
5120       It = PC->varlist_begin();
5121       Et = PC->varlist_end();
5122     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5123       auto *PC = cast<OMPFirstprivateClause>(Cl);
5124       I = PC->private_copies().begin();
5125       It = PC->varlist_begin();
5126       Et = PC->varlist_end();
5127     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5128       auto *PC = cast<OMPLastprivateClause>(Cl);
5129       I = PC->private_copies().begin();
5130       It = PC->varlist_begin();
5131       Et = PC->varlist_end();
5132     } else if (Cl->getClauseKind() == OMPC_linear) {
5133       auto *PC = cast<OMPLinearClause>(Cl);
5134       I = PC->privates().begin();
5135       It = PC->varlist_begin();
5136       Et = PC->varlist_end();
5137     } else if (Cl->getClauseKind() == OMPC_reduction) {
5138       auto *PC = cast<OMPReductionClause>(Cl);
5139       I = PC->privates().begin();
5140       It = PC->varlist_begin();
5141       Et = PC->varlist_end();
5142     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5143       auto *PC = cast<OMPTaskReductionClause>(Cl);
5144       I = PC->privates().begin();
5145       It = PC->varlist_begin();
5146       Et = PC->varlist_end();
5147     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5148       auto *PC = cast<OMPInReductionClause>(Cl);
5149       I = PC->privates().begin();
5150       It = PC->varlist_begin();
5151       Et = PC->varlist_end();
5152     } else {
5153       llvm_unreachable("Expected private clause.");
5154     }
5155     for (Expr *E : llvm::make_range(It, Et)) {
5156       if (!*I) {
5157         ++I;
5158         continue;
5159       }
5160       SourceLocation ELoc;
5161       SourceRange ERange;
5162       Expr *SimpleRefExpr = E;
5163       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5164                                 /*AllowArraySection=*/true);
5165       DeclToCopy.try_emplace(Res.first,
5166                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5167       ++I;
5168     }
5169   }
5170   for (OMPClause *C : AllocateRange) {
5171     auto *AC = cast<OMPAllocateClause>(C);
5172     if (S.getLangOpts().OpenMP >= 50 &&
5173         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5174         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5175         AC->getAllocator()) {
5176       Expr *Allocator = AC->getAllocator();
5177       // OpenMP, 2.12.5 target Construct
5178       // Memory allocators that do not appear in a uses_allocators clause cannot
5179       // appear as an allocator in an allocate clause or be used in the target
5180       // region unless a requires directive with the dynamic_allocators clause
5181       // is present in the same compilation unit.
5182       AllocatorChecker Checker(Stack);
5183       if (Checker.Visit(Allocator))
5184         S.Diag(Allocator->getExprLoc(),
5185                diag::err_omp_allocator_not_in_uses_allocators)
5186             << Allocator->getSourceRange();
5187     }
5188     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5189         getAllocatorKind(S, Stack, AC->getAllocator());
5190     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5191     // For task, taskloop or target directives, allocation requests to memory
5192     // allocators with the trait access set to thread result in unspecified
5193     // behavior.
5194     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5195         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5196          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5197       S.Diag(AC->getAllocator()->getExprLoc(),
5198              diag::warn_omp_allocate_thread_on_task_target_directive)
5199           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5200     }
5201     for (Expr *E : AC->varlists()) {
5202       SourceLocation ELoc;
5203       SourceRange ERange;
5204       Expr *SimpleRefExpr = E;
5205       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5206       ValueDecl *VD = Res.first;
5207       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5208       if (!isOpenMPPrivate(Data.CKind)) {
5209         S.Diag(E->getExprLoc(),
5210                diag::err_omp_expected_private_copy_for_allocate);
5211         continue;
5212       }
5213       VarDecl *PrivateVD = DeclToCopy[VD];
5214       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5215                                             AllocatorKind, AC->getAllocator()))
5216         continue;
5217       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5218                                 E->getSourceRange());
5219     }
5220   }
5221 }
5222 
5223 namespace {
5224 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5225 ///
5226 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5227 /// context. DeclRefExpr used inside the new context are changed to refer to the
5228 /// captured variable instead.
5229 class CaptureVars : public TreeTransform<CaptureVars> {
5230   using BaseTransform = TreeTransform<CaptureVars>;
5231 
5232 public:
CaptureVars(Sema & Actions)5233   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5234 
AlwaysRebuild()5235   bool AlwaysRebuild() { return true; }
5236 };
5237 } // namespace
5238 
precomputeExpr(Sema & Actions,SmallVectorImpl<Stmt * > & BodyStmts,Expr * E,StringRef Name)5239 static VarDecl *precomputeExpr(Sema &Actions,
5240                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5241                                StringRef Name) {
5242   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5243   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5244                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5245   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5246       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5247   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5248   BodyStmts.push_back(NewDeclStmt);
5249   return NewVar;
5250 }
5251 
5252 /// Create a closure that computes the number of iterations of a loop.
5253 ///
5254 /// \param Actions   The Sema object.
5255 /// \param LogicalTy Type for the logical iteration number.
5256 /// \param Rel       Comparison operator of the loop condition.
5257 /// \param StartExpr Value of the loop counter at the first iteration.
5258 /// \param StopExpr  Expression the loop counter is compared against in the loop
5259 /// condition. \param StepExpr      Amount of increment after each iteration.
5260 ///
5261 /// \return Closure (CapturedStmt) of the distance calculation.
buildDistanceFunc(Sema & Actions,QualType LogicalTy,BinaryOperator::Opcode Rel,Expr * StartExpr,Expr * StopExpr,Expr * StepExpr)5262 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5263                                        BinaryOperator::Opcode Rel,
5264                                        Expr *StartExpr, Expr *StopExpr,
5265                                        Expr *StepExpr) {
5266   ASTContext &Ctx = Actions.getASTContext();
5267   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5268 
5269   // Captured regions currently don't support return values, we use an
5270   // out-parameter instead. All inputs are implicit captures.
5271   // TODO: Instead of capturing each DeclRefExpr occurring in
5272   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5273   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5274   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5275                                           {StringRef(), QualType()}};
5276   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5277 
5278   Stmt *Body;
5279   {
5280     Sema::CompoundScopeRAII CompoundScope(Actions);
5281     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5282 
5283     // Get the LValue expression for the result.
5284     ImplicitParamDecl *DistParam = CS->getParam(0);
5285     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5286         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5287 
5288     SmallVector<Stmt *, 4> BodyStmts;
5289 
5290     // Capture all referenced variable references.
5291     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5292     // CapturedStmt, we could compute them before and capture the result, to be
5293     // used jointly with the LoopVar function.
5294     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5295     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5296     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5297     auto BuildVarRef = [&](VarDecl *VD) {
5298       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5299     };
5300 
5301     IntegerLiteral *Zero = IntegerLiteral::Create(
5302         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5303     Expr *Dist;
5304     if (Rel == BO_NE) {
5305       // When using a != comparison, the increment can be +1 or -1. This can be
5306       // dynamic at runtime, so we need to check for the direction.
5307       Expr *IsNegStep = AssertSuccess(
5308           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5309 
5310       // Positive increment.
5311       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5312           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5313       ForwardRange = AssertSuccess(
5314           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5315       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5316           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5317 
5318       // Negative increment.
5319       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5320           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5321       BackwardRange = AssertSuccess(
5322           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5323       Expr *NegIncAmount = AssertSuccess(
5324           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5325       Expr *BackwardDist = AssertSuccess(
5326           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5327 
5328       // Use the appropriate case.
5329       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5330           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5331     } else {
5332       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5333              "Expected one of these relational operators");
5334 
5335       // We can derive the direction from any other comparison operator. It is
5336       // non well-formed OpenMP if Step increments/decrements in the other
5337       // directions. Whether at least the first iteration passes the loop
5338       // condition.
5339       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5340           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5341 
5342       // Compute the range between first and last counter value.
5343       Expr *Range;
5344       if (Rel == BO_GE || Rel == BO_GT)
5345         Range = AssertSuccess(Actions.BuildBinOp(
5346             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5347       else
5348         Range = AssertSuccess(Actions.BuildBinOp(
5349             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5350 
5351       // Ensure unsigned range space.
5352       Range =
5353           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5354 
5355       if (Rel == BO_LE || Rel == BO_GE) {
5356         // Add one to the range if the relational operator is inclusive.
5357         Range = AssertSuccess(Actions.BuildBinOp(
5358             nullptr, {}, BO_Add, Range,
5359             Actions.ActOnIntegerConstant(SourceLocation(), 1).get()));
5360       }
5361 
5362       // Divide by the absolute step amount.
5363       Expr *Divisor = BuildVarRef(NewStep);
5364       if (Rel == BO_GE || Rel == BO_GT)
5365         Divisor =
5366             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5367       Dist = AssertSuccess(
5368           Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5369 
5370       // If there is not at least one iteration, the range contains garbage. Fix
5371       // to zero in this case.
5372       Dist = AssertSuccess(
5373           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5374     }
5375 
5376     // Assign the result to the out-parameter.
5377     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5378         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5379     BodyStmts.push_back(ResultAssign);
5380 
5381     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5382   }
5383 
5384   return cast<CapturedStmt>(
5385       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5386 }
5387 
5388 /// Create a closure that computes the loop variable from the logical iteration
5389 /// number.
5390 ///
5391 /// \param Actions   The Sema object.
5392 /// \param LoopVarTy Type for the loop variable used for result value.
5393 /// \param LogicalTy Type for the logical iteration number.
5394 /// \param StartExpr Value of the loop counter at the first iteration.
5395 /// \param Step      Amount of increment after each iteration.
5396 /// \param Deref     Whether the loop variable is a dereference of the loop
5397 /// counter variable.
5398 ///
5399 /// \return Closure (CapturedStmt) of the loop value calculation.
buildLoopVarFunc(Sema & Actions,QualType LoopVarTy,QualType LogicalTy,DeclRefExpr * StartExpr,Expr * Step,bool Deref)5400 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5401                                       QualType LogicalTy,
5402                                       DeclRefExpr *StartExpr, Expr *Step,
5403                                       bool Deref) {
5404   ASTContext &Ctx = Actions.getASTContext();
5405 
5406   // Pass the result as an out-parameter. Passing as return value would require
5407   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5408   // invoke a copy constructor.
5409   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5410   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5411                                           {"Logical", LogicalTy},
5412                                           {StringRef(), QualType()}};
5413   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5414 
5415   // Capture the initial iterator which represents the LoopVar value at the
5416   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5417   // it in every iteration, capture it by value before it is modified.
5418   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5419   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5420                                             Sema::TryCapture_ExplicitByVal, {});
5421   (void)Invalid;
5422   assert(!Invalid && "Expecting capture-by-value to work.");
5423 
5424   Expr *Body;
5425   {
5426     Sema::CompoundScopeRAII CompoundScope(Actions);
5427     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5428 
5429     ImplicitParamDecl *TargetParam = CS->getParam(0);
5430     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5431         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5432     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5433     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5434         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5435 
5436     // Capture the Start expression.
5437     CaptureVars Recap(Actions);
5438     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5439     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5440 
5441     Expr *Skip = AssertSuccess(
5442         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5443     // TODO: Explicitly cast to the iterator's difference_type instead of
5444     // relying on implicit conversion.
5445     Expr *Advanced =
5446         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5447 
5448     if (Deref) {
5449       // For range-based for-loops convert the loop counter value to a concrete
5450       // loop variable value by dereferencing the iterator.
5451       Advanced =
5452           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5453     }
5454 
5455     // Assign the result to the output parameter.
5456     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5457                                             BO_Assign, TargetRef, Advanced));
5458   }
5459   return cast<CapturedStmt>(
5460       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5461 }
5462 
ActOnOpenMPCanonicalLoop(Stmt * AStmt)5463 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5464   ASTContext &Ctx = getASTContext();
5465 
5466   // Extract the common elements of ForStmt and CXXForRangeStmt:
5467   // Loop variable, repeat condition, increment
5468   Expr *Cond, *Inc;
5469   VarDecl *LIVDecl, *LUVDecl;
5470   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5471     Stmt *Init = For->getInit();
5472     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5473       // For statement declares loop variable.
5474       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5475     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5476       // For statement reuses variable.
5477       assert(LCAssign->getOpcode() == BO_Assign &&
5478              "init part must be a loop variable assignment");
5479       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5480       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5481     } else
5482       llvm_unreachable("Cannot determine loop variable");
5483     LUVDecl = LIVDecl;
5484 
5485     Cond = For->getCond();
5486     Inc = For->getInc();
5487   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5488     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5489     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5490     LUVDecl = RangeFor->getLoopVariable();
5491 
5492     Cond = RangeFor->getCond();
5493     Inc = RangeFor->getInc();
5494   } else
5495     llvm_unreachable("unhandled kind of loop");
5496 
5497   QualType CounterTy = LIVDecl->getType();
5498   QualType LVTy = LUVDecl->getType();
5499 
5500   // Analyze the loop condition.
5501   Expr *LHS, *RHS;
5502   BinaryOperator::Opcode CondRel;
5503   Cond = Cond->IgnoreImplicit();
5504   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5505     LHS = CondBinExpr->getLHS();
5506     RHS = CondBinExpr->getRHS();
5507     CondRel = CondBinExpr->getOpcode();
5508   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5509     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5510     LHS = CondCXXOp->getArg(0);
5511     RHS = CondCXXOp->getArg(1);
5512     switch (CondCXXOp->getOperator()) {
5513     case OO_ExclaimEqual:
5514       CondRel = BO_NE;
5515       break;
5516     case OO_Less:
5517       CondRel = BO_LT;
5518       break;
5519     case OO_LessEqual:
5520       CondRel = BO_LE;
5521       break;
5522     case OO_Greater:
5523       CondRel = BO_GT;
5524       break;
5525     case OO_GreaterEqual:
5526       CondRel = BO_GE;
5527       break;
5528     default:
5529       llvm_unreachable("unexpected iterator operator");
5530     }
5531   } else
5532     llvm_unreachable("unexpected loop condition");
5533 
5534   // Normalize such that the loop counter is on the LHS.
5535   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5536       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5537     std::swap(LHS, RHS);
5538     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5539   }
5540   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5541 
5542   // Decide the bit width for the logical iteration counter. By default use the
5543   // unsigned ptrdiff_t integer size (for iterators and pointers).
5544   // TODO: For iterators, use iterator::difference_type,
5545   // std::iterator_traits<>::difference_type or decltype(it - end).
5546   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5547   if (CounterTy->isIntegerType()) {
5548     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5549     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5550   }
5551 
5552   // Analyze the loop increment.
5553   Expr *Step;
5554   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5555     int Direction;
5556     switch (IncUn->getOpcode()) {
5557     case UO_PreInc:
5558     case UO_PostInc:
5559       Direction = 1;
5560       break;
5561     case UO_PreDec:
5562     case UO_PostDec:
5563       Direction = -1;
5564       break;
5565     default:
5566       llvm_unreachable("unhandled unary increment operator");
5567     }
5568     Step = IntegerLiteral::Create(
5569         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5570   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5571     if (IncBin->getOpcode() == BO_AddAssign) {
5572       Step = IncBin->getRHS();
5573     } else if (IncBin->getOpcode() == BO_SubAssign) {
5574       Step =
5575           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5576     } else
5577       llvm_unreachable("unhandled binary increment operator");
5578   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5579     switch (CondCXXOp->getOperator()) {
5580     case OO_PlusPlus:
5581       Step = IntegerLiteral::Create(
5582           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5583       break;
5584     case OO_MinusMinus:
5585       Step = IntegerLiteral::Create(
5586           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5587       break;
5588     case OO_PlusEqual:
5589       Step = CondCXXOp->getArg(1);
5590       break;
5591     case OO_MinusEqual:
5592       Step = AssertSuccess(
5593           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5594       break;
5595     default:
5596       llvm_unreachable("unhandled overloaded increment operator");
5597     }
5598   } else
5599     llvm_unreachable("unknown increment expression");
5600 
5601   CapturedStmt *DistanceFunc =
5602       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5603   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5604       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5605   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5606                                         {}, nullptr, nullptr, {}, nullptr);
5607   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5608                                   LoopVarFunc, LVRef);
5609 }
5610 
ActOnOpenMPLoopnest(Stmt * AStmt)5611 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5612   // Handle a literal loop.
5613   if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5614     return ActOnOpenMPCanonicalLoop(AStmt);
5615 
5616   // If not a literal loop, it must be the result of a loop transformation.
5617   OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5618   assert(
5619       isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5620       "Loop transformation directive expected");
5621   return LoopTransform;
5622 }
5623 
5624 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5625                                             CXXScopeSpec &MapperIdScopeSpec,
5626                                             const DeclarationNameInfo &MapperId,
5627                                             QualType Type,
5628                                             Expr *UnresolvedMapper);
5629 
5630 /// Perform DFS through the structure/class data members trying to find
5631 /// member(s) with user-defined 'default' mapper and generate implicit map
5632 /// clauses for such members with the found 'default' mapper.
5633 static void
processImplicitMapsWithDefaultMappers(Sema & S,DSAStackTy * Stack,SmallVectorImpl<OMPClause * > & Clauses)5634 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5635                                       SmallVectorImpl<OMPClause *> &Clauses) {
5636   // Check for the deault mapper for data members.
5637   if (S.getLangOpts().OpenMP < 50)
5638     return;
5639   SmallVector<OMPClause *, 4> ImplicitMaps;
5640   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5641     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5642     if (!C)
5643       continue;
5644     SmallVector<Expr *, 4> SubExprs;
5645     auto *MI = C->mapperlist_begin();
5646     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5647          ++I, ++MI) {
5648       // Expression is mapped using mapper - skip it.
5649       if (*MI)
5650         continue;
5651       Expr *E = *I;
5652       // Expression is dependent - skip it, build the mapper when it gets
5653       // instantiated.
5654       if (E->isTypeDependent() || E->isValueDependent() ||
5655           E->containsUnexpandedParameterPack())
5656         continue;
5657       // Array section - need to check for the mapping of the array section
5658       // element.
5659       QualType CanonType = E->getType().getCanonicalType();
5660       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5661         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5662         QualType BaseType =
5663             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5664         QualType ElemType;
5665         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5666           ElemType = ATy->getElementType();
5667         else
5668           ElemType = BaseType->getPointeeType();
5669         CanonType = ElemType;
5670       }
5671 
5672       // DFS over data members in structures/classes.
5673       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5674           1, {CanonType, nullptr});
5675       llvm::DenseMap<const Type *, Expr *> Visited;
5676       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5677           1, {nullptr, 1});
5678       while (!Types.empty()) {
5679         QualType BaseType;
5680         FieldDecl *CurFD;
5681         std::tie(BaseType, CurFD) = Types.pop_back_val();
5682         while (ParentChain.back().second == 0)
5683           ParentChain.pop_back();
5684         --ParentChain.back().second;
5685         if (BaseType.isNull())
5686           continue;
5687         // Only structs/classes are allowed to have mappers.
5688         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5689         if (!RD)
5690           continue;
5691         auto It = Visited.find(BaseType.getTypePtr());
5692         if (It == Visited.end()) {
5693           // Try to find the associated user-defined mapper.
5694           CXXScopeSpec MapperIdScopeSpec;
5695           DeclarationNameInfo DefaultMapperId;
5696           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5697               &S.Context.Idents.get("default")));
5698           DefaultMapperId.setLoc(E->getExprLoc());
5699           ExprResult ER = buildUserDefinedMapperRef(
5700               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5701               BaseType, /*UnresolvedMapper=*/nullptr);
5702           if (ER.isInvalid())
5703             continue;
5704           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5705         }
5706         // Found default mapper.
5707         if (It->second) {
5708           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5709                                                      VK_LValue, OK_Ordinary, E);
5710           OE->setIsUnique(/*V=*/true);
5711           Expr *BaseExpr = OE;
5712           for (const auto &P : ParentChain) {
5713             if (P.first) {
5714               BaseExpr = S.BuildMemberExpr(
5715                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5716                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
5717                   DeclAccessPair::make(P.first, P.first->getAccess()),
5718                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5719                   P.first->getType(), VK_LValue, OK_Ordinary);
5720               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5721             }
5722           }
5723           if (CurFD)
5724             BaseExpr = S.BuildMemberExpr(
5725                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5726                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5727                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5728                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5729                 CurFD->getType(), VK_LValue, OK_Ordinary);
5730           SubExprs.push_back(BaseExpr);
5731           continue;
5732         }
5733         // Check for the "default" mapper for data members.
5734         bool FirstIter = true;
5735         for (FieldDecl *FD : RD->fields()) {
5736           if (!FD)
5737             continue;
5738           QualType FieldTy = FD->getType();
5739           if (FieldTy.isNull() ||
5740               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5741             continue;
5742           if (FirstIter) {
5743             FirstIter = false;
5744             ParentChain.emplace_back(CurFD, 1);
5745           } else {
5746             ++ParentChain.back().second;
5747           }
5748           Types.emplace_back(FieldTy, FD);
5749         }
5750       }
5751     }
5752     if (SubExprs.empty())
5753       continue;
5754     CXXScopeSpec MapperIdScopeSpec;
5755     DeclarationNameInfo MapperId;
5756     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5757             C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5758             MapperIdScopeSpec, MapperId, C->getMapType(),
5759             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5760             SubExprs, OMPVarListLocTy()))
5761       Clauses.push_back(NewClause);
5762   }
5763 }
5764 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5765 StmtResult Sema::ActOnOpenMPExecutableDirective(
5766     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5767     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5768     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5769   StmtResult Res = StmtError();
5770   // First check CancelRegion which is then used in checkNestingOfRegions.
5771   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5772       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5773                             StartLoc))
5774     return StmtError();
5775 
5776   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5777   VarsWithInheritedDSAType VarsWithInheritedDSA;
5778   bool ErrorFound = false;
5779   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5780   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5781       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5782       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5783     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5784 
5785     // Check default data sharing attributes for referenced variables.
5786     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5787     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5788     Stmt *S = AStmt;
5789     while (--ThisCaptureLevel >= 0)
5790       S = cast<CapturedStmt>(S)->getCapturedStmt();
5791     DSAChecker.Visit(S);
5792     if (!isOpenMPTargetDataManagementDirective(Kind) &&
5793         !isOpenMPTaskingDirective(Kind)) {
5794       // Visit subcaptures to generate implicit clauses for captured vars.
5795       auto *CS = cast<CapturedStmt>(AStmt);
5796       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5797       getOpenMPCaptureRegions(CaptureRegions, Kind);
5798       // Ignore outer tasking regions for target directives.
5799       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5800         CS = cast<CapturedStmt>(CS->getCapturedStmt());
5801       DSAChecker.visitSubCaptures(CS);
5802     }
5803     if (DSAChecker.isErrorFound())
5804       return StmtError();
5805     // Generate list of implicitly defined firstprivate variables.
5806     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5807 
5808     SmallVector<Expr *, 4> ImplicitFirstprivates(
5809         DSAChecker.getImplicitFirstprivate().begin(),
5810         DSAChecker.getImplicitFirstprivate().end());
5811     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5812     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5813     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5814         ImplicitMapModifiers[DefaultmapKindNum];
5815     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5816         ImplicitMapModifiersLoc[DefaultmapKindNum];
5817     // Get the original location of present modifier from Defaultmap clause.
5818     SourceLocation PresentModifierLocs[DefaultmapKindNum];
5819     for (OMPClause *C : Clauses) {
5820       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5821         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5822           PresentModifierLocs[DMC->getDefaultmapKind()] =
5823               DMC->getDefaultmapModifierLoc();
5824     }
5825     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5826       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5827       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5828         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5829             Kind, static_cast<OpenMPMapClauseKind>(I));
5830         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5831       }
5832       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5833           DSAChecker.getImplicitMapModifier(Kind);
5834       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5835                                       ImplicitModifier.end());
5836       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5837                   ImplicitModifier.size(), PresentModifierLocs[VC]);
5838     }
5839     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5840     for (OMPClause *C : Clauses) {
5841       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5842         for (Expr *E : IRC->taskgroup_descriptors())
5843           if (E)
5844             ImplicitFirstprivates.emplace_back(E);
5845       }
5846       // OpenMP 5.0, 2.10.1 task Construct
5847       // [detach clause]... The event-handle will be considered as if it was
5848       // specified on a firstprivate clause.
5849       if (auto *DC = dyn_cast<OMPDetachClause>(C))
5850         ImplicitFirstprivates.push_back(DC->getEventHandler());
5851     }
5852     if (!ImplicitFirstprivates.empty()) {
5853       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5854               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5855               SourceLocation())) {
5856         ClausesWithImplicit.push_back(Implicit);
5857         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5858                      ImplicitFirstprivates.size();
5859       } else {
5860         ErrorFound = true;
5861       }
5862     }
5863     // OpenMP 5.0 [2.19.7]
5864     // If a list item appears in a reduction, lastprivate or linear
5865     // clause on a combined target construct then it is treated as
5866     // if it also appears in a map clause with a map-type of tofrom
5867     if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
5868         isOpenMPTargetExecutionDirective(Kind)) {
5869       SmallVector<Expr *, 4> ImplicitExprs;
5870       for (OMPClause *C : Clauses) {
5871         if (auto *RC = dyn_cast<OMPReductionClause>(C))
5872           for (Expr *E : RC->varlists())
5873             if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
5874               ImplicitExprs.emplace_back(E);
5875       }
5876       if (!ImplicitExprs.empty()) {
5877         ArrayRef<Expr *> Exprs = ImplicitExprs;
5878         CXXScopeSpec MapperIdScopeSpec;
5879         DeclarationNameInfo MapperId;
5880         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5881                 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
5882                 MapperId, OMPC_MAP_tofrom,
5883                 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5884                 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
5885           ClausesWithImplicit.emplace_back(Implicit);
5886       }
5887     }
5888     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5889       int ClauseKindCnt = -1;
5890       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5891         ++ClauseKindCnt;
5892         if (ImplicitMap.empty())
5893           continue;
5894         CXXScopeSpec MapperIdScopeSpec;
5895         DeclarationNameInfo MapperId;
5896         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5897         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5898                 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5899                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5900                 SourceLocation(), SourceLocation(), ImplicitMap,
5901                 OMPVarListLocTy())) {
5902           ClausesWithImplicit.emplace_back(Implicit);
5903           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5904                         ImplicitMap.size();
5905         } else {
5906           ErrorFound = true;
5907         }
5908       }
5909     }
5910     // Build expressions for implicit maps of data members with 'default'
5911     // mappers.
5912     if (LangOpts.OpenMP >= 50)
5913       processImplicitMapsWithDefaultMappers(*this, DSAStack,
5914                                             ClausesWithImplicit);
5915   }
5916 
5917   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5918   switch (Kind) {
5919   case OMPD_parallel:
5920     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5921                                        EndLoc);
5922     AllowedNameModifiers.push_back(OMPD_parallel);
5923     break;
5924   case OMPD_simd:
5925     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5926                                    VarsWithInheritedDSA);
5927     if (LangOpts.OpenMP >= 50)
5928       AllowedNameModifiers.push_back(OMPD_simd);
5929     break;
5930   case OMPD_tile:
5931     Res =
5932         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5933     break;
5934   case OMPD_unroll:
5935     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
5936                                      EndLoc);
5937     break;
5938   case OMPD_for:
5939     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5940                                   VarsWithInheritedDSA);
5941     break;
5942   case OMPD_for_simd:
5943     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5944                                       EndLoc, VarsWithInheritedDSA);
5945     if (LangOpts.OpenMP >= 50)
5946       AllowedNameModifiers.push_back(OMPD_simd);
5947     break;
5948   case OMPD_sections:
5949     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5950                                        EndLoc);
5951     break;
5952   case OMPD_section:
5953     assert(ClausesWithImplicit.empty() &&
5954            "No clauses are allowed for 'omp section' directive");
5955     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5956     break;
5957   case OMPD_single:
5958     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5959                                      EndLoc);
5960     break;
5961   case OMPD_master:
5962     assert(ClausesWithImplicit.empty() &&
5963            "No clauses are allowed for 'omp master' directive");
5964     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5965     break;
5966   case OMPD_masked:
5967     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
5968                                      EndLoc);
5969     break;
5970   case OMPD_critical:
5971     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5972                                        StartLoc, EndLoc);
5973     break;
5974   case OMPD_parallel_for:
5975     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5976                                           EndLoc, VarsWithInheritedDSA);
5977     AllowedNameModifiers.push_back(OMPD_parallel);
5978     break;
5979   case OMPD_parallel_for_simd:
5980     Res = ActOnOpenMPParallelForSimdDirective(
5981         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5982     AllowedNameModifiers.push_back(OMPD_parallel);
5983     if (LangOpts.OpenMP >= 50)
5984       AllowedNameModifiers.push_back(OMPD_simd);
5985     break;
5986   case OMPD_parallel_master:
5987     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5988                                                StartLoc, EndLoc);
5989     AllowedNameModifiers.push_back(OMPD_parallel);
5990     break;
5991   case OMPD_parallel_sections:
5992     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5993                                                StartLoc, EndLoc);
5994     AllowedNameModifiers.push_back(OMPD_parallel);
5995     break;
5996   case OMPD_task:
5997     Res =
5998         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5999     AllowedNameModifiers.push_back(OMPD_task);
6000     break;
6001   case OMPD_taskyield:
6002     assert(ClausesWithImplicit.empty() &&
6003            "No clauses are allowed for 'omp taskyield' directive");
6004     assert(AStmt == nullptr &&
6005            "No associated statement allowed for 'omp taskyield' directive");
6006     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6007     break;
6008   case OMPD_barrier:
6009     assert(ClausesWithImplicit.empty() &&
6010            "No clauses are allowed for 'omp barrier' directive");
6011     assert(AStmt == nullptr &&
6012            "No associated statement allowed for 'omp barrier' directive");
6013     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6014     break;
6015   case OMPD_taskwait:
6016     assert(ClausesWithImplicit.empty() &&
6017            "No clauses are allowed for 'omp taskwait' directive");
6018     assert(AStmt == nullptr &&
6019            "No associated statement allowed for 'omp taskwait' directive");
6020     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
6021     break;
6022   case OMPD_taskgroup:
6023     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6024                                         EndLoc);
6025     break;
6026   case OMPD_flush:
6027     assert(AStmt == nullptr &&
6028            "No associated statement allowed for 'omp flush' directive");
6029     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6030     break;
6031   case OMPD_depobj:
6032     assert(AStmt == nullptr &&
6033            "No associated statement allowed for 'omp depobj' directive");
6034     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6035     break;
6036   case OMPD_scan:
6037     assert(AStmt == nullptr &&
6038            "No associated statement allowed for 'omp scan' directive");
6039     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6040     break;
6041   case OMPD_ordered:
6042     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6043                                       EndLoc);
6044     break;
6045   case OMPD_atomic:
6046     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6047                                      EndLoc);
6048     break;
6049   case OMPD_teams:
6050     Res =
6051         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6052     break;
6053   case OMPD_target:
6054     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6055                                      EndLoc);
6056     AllowedNameModifiers.push_back(OMPD_target);
6057     break;
6058   case OMPD_target_parallel:
6059     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6060                                              StartLoc, EndLoc);
6061     AllowedNameModifiers.push_back(OMPD_target);
6062     AllowedNameModifiers.push_back(OMPD_parallel);
6063     break;
6064   case OMPD_target_parallel_for:
6065     Res = ActOnOpenMPTargetParallelForDirective(
6066         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6067     AllowedNameModifiers.push_back(OMPD_target);
6068     AllowedNameModifiers.push_back(OMPD_parallel);
6069     break;
6070   case OMPD_cancellation_point:
6071     assert(ClausesWithImplicit.empty() &&
6072            "No clauses are allowed for 'omp cancellation point' directive");
6073     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6074                                "cancellation point' directive");
6075     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6076     break;
6077   case OMPD_cancel:
6078     assert(AStmt == nullptr &&
6079            "No associated statement allowed for 'omp cancel' directive");
6080     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6081                                      CancelRegion);
6082     AllowedNameModifiers.push_back(OMPD_cancel);
6083     break;
6084   case OMPD_target_data:
6085     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6086                                          EndLoc);
6087     AllowedNameModifiers.push_back(OMPD_target_data);
6088     break;
6089   case OMPD_target_enter_data:
6090     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6091                                               EndLoc, AStmt);
6092     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6093     break;
6094   case OMPD_target_exit_data:
6095     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6096                                              EndLoc, AStmt);
6097     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6098     break;
6099   case OMPD_taskloop:
6100     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6101                                        EndLoc, VarsWithInheritedDSA);
6102     AllowedNameModifiers.push_back(OMPD_taskloop);
6103     break;
6104   case OMPD_taskloop_simd:
6105     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6106                                            EndLoc, VarsWithInheritedDSA);
6107     AllowedNameModifiers.push_back(OMPD_taskloop);
6108     if (LangOpts.OpenMP >= 50)
6109       AllowedNameModifiers.push_back(OMPD_simd);
6110     break;
6111   case OMPD_master_taskloop:
6112     Res = ActOnOpenMPMasterTaskLoopDirective(
6113         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6114     AllowedNameModifiers.push_back(OMPD_taskloop);
6115     break;
6116   case OMPD_master_taskloop_simd:
6117     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6118         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6119     AllowedNameModifiers.push_back(OMPD_taskloop);
6120     if (LangOpts.OpenMP >= 50)
6121       AllowedNameModifiers.push_back(OMPD_simd);
6122     break;
6123   case OMPD_parallel_master_taskloop:
6124     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6125         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6126     AllowedNameModifiers.push_back(OMPD_taskloop);
6127     AllowedNameModifiers.push_back(OMPD_parallel);
6128     break;
6129   case OMPD_parallel_master_taskloop_simd:
6130     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6131         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6132     AllowedNameModifiers.push_back(OMPD_taskloop);
6133     AllowedNameModifiers.push_back(OMPD_parallel);
6134     if (LangOpts.OpenMP >= 50)
6135       AllowedNameModifiers.push_back(OMPD_simd);
6136     break;
6137   case OMPD_distribute:
6138     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6139                                          EndLoc, VarsWithInheritedDSA);
6140     break;
6141   case OMPD_target_update:
6142     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6143                                            EndLoc, AStmt);
6144     AllowedNameModifiers.push_back(OMPD_target_update);
6145     break;
6146   case OMPD_distribute_parallel_for:
6147     Res = ActOnOpenMPDistributeParallelForDirective(
6148         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6149     AllowedNameModifiers.push_back(OMPD_parallel);
6150     break;
6151   case OMPD_distribute_parallel_for_simd:
6152     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6153         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6154     AllowedNameModifiers.push_back(OMPD_parallel);
6155     if (LangOpts.OpenMP >= 50)
6156       AllowedNameModifiers.push_back(OMPD_simd);
6157     break;
6158   case OMPD_distribute_simd:
6159     Res = ActOnOpenMPDistributeSimdDirective(
6160         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6161     if (LangOpts.OpenMP >= 50)
6162       AllowedNameModifiers.push_back(OMPD_simd);
6163     break;
6164   case OMPD_target_parallel_for_simd:
6165     Res = ActOnOpenMPTargetParallelForSimdDirective(
6166         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6167     AllowedNameModifiers.push_back(OMPD_target);
6168     AllowedNameModifiers.push_back(OMPD_parallel);
6169     if (LangOpts.OpenMP >= 50)
6170       AllowedNameModifiers.push_back(OMPD_simd);
6171     break;
6172   case OMPD_target_simd:
6173     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6174                                          EndLoc, VarsWithInheritedDSA);
6175     AllowedNameModifiers.push_back(OMPD_target);
6176     if (LangOpts.OpenMP >= 50)
6177       AllowedNameModifiers.push_back(OMPD_simd);
6178     break;
6179   case OMPD_teams_distribute:
6180     Res = ActOnOpenMPTeamsDistributeDirective(
6181         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6182     break;
6183   case OMPD_teams_distribute_simd:
6184     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6185         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6186     if (LangOpts.OpenMP >= 50)
6187       AllowedNameModifiers.push_back(OMPD_simd);
6188     break;
6189   case OMPD_teams_distribute_parallel_for_simd:
6190     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6191         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6192     AllowedNameModifiers.push_back(OMPD_parallel);
6193     if (LangOpts.OpenMP >= 50)
6194       AllowedNameModifiers.push_back(OMPD_simd);
6195     break;
6196   case OMPD_teams_distribute_parallel_for:
6197     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6198         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6199     AllowedNameModifiers.push_back(OMPD_parallel);
6200     break;
6201   case OMPD_target_teams:
6202     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6203                                           EndLoc);
6204     AllowedNameModifiers.push_back(OMPD_target);
6205     break;
6206   case OMPD_target_teams_distribute:
6207     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6208         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6209     AllowedNameModifiers.push_back(OMPD_target);
6210     break;
6211   case OMPD_target_teams_distribute_parallel_for:
6212     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6213         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6214     AllowedNameModifiers.push_back(OMPD_target);
6215     AllowedNameModifiers.push_back(OMPD_parallel);
6216     break;
6217   case OMPD_target_teams_distribute_parallel_for_simd:
6218     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6219         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6220     AllowedNameModifiers.push_back(OMPD_target);
6221     AllowedNameModifiers.push_back(OMPD_parallel);
6222     if (LangOpts.OpenMP >= 50)
6223       AllowedNameModifiers.push_back(OMPD_simd);
6224     break;
6225   case OMPD_target_teams_distribute_simd:
6226     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6227         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6228     AllowedNameModifiers.push_back(OMPD_target);
6229     if (LangOpts.OpenMP >= 50)
6230       AllowedNameModifiers.push_back(OMPD_simd);
6231     break;
6232   case OMPD_interop:
6233     assert(AStmt == nullptr &&
6234            "No associated statement allowed for 'omp interop' directive");
6235     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6236     break;
6237   case OMPD_dispatch:
6238     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6239                                        EndLoc);
6240     break;
6241   case OMPD_declare_target:
6242   case OMPD_end_declare_target:
6243   case OMPD_threadprivate:
6244   case OMPD_allocate:
6245   case OMPD_declare_reduction:
6246   case OMPD_declare_mapper:
6247   case OMPD_declare_simd:
6248   case OMPD_requires:
6249   case OMPD_declare_variant:
6250   case OMPD_begin_declare_variant:
6251   case OMPD_end_declare_variant:
6252     llvm_unreachable("OpenMP Directive is not allowed");
6253   case OMPD_unknown:
6254   default:
6255     llvm_unreachable("Unknown OpenMP directive");
6256   }
6257 
6258   ErrorFound = Res.isInvalid() || ErrorFound;
6259 
6260   // Check variables in the clauses if default(none) or
6261   // default(firstprivate) was specified.
6262   if (DSAStack->getDefaultDSA() == DSA_none ||
6263       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6264     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6265     for (OMPClause *C : Clauses) {
6266       switch (C->getClauseKind()) {
6267       case OMPC_num_threads:
6268       case OMPC_dist_schedule:
6269         // Do not analyse if no parent teams directive.
6270         if (isOpenMPTeamsDirective(Kind))
6271           break;
6272         continue;
6273       case OMPC_if:
6274         if (isOpenMPTeamsDirective(Kind) &&
6275             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6276           break;
6277         if (isOpenMPParallelDirective(Kind) &&
6278             isOpenMPTaskLoopDirective(Kind) &&
6279             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6280           break;
6281         continue;
6282       case OMPC_schedule:
6283       case OMPC_detach:
6284         break;
6285       case OMPC_grainsize:
6286       case OMPC_num_tasks:
6287       case OMPC_final:
6288       case OMPC_priority:
6289       case OMPC_novariants:
6290       case OMPC_nocontext:
6291         // Do not analyze if no parent parallel directive.
6292         if (isOpenMPParallelDirective(Kind))
6293           break;
6294         continue;
6295       case OMPC_ordered:
6296       case OMPC_device:
6297       case OMPC_num_teams:
6298       case OMPC_thread_limit:
6299       case OMPC_hint:
6300       case OMPC_collapse:
6301       case OMPC_safelen:
6302       case OMPC_simdlen:
6303       case OMPC_sizes:
6304       case OMPC_default:
6305       case OMPC_proc_bind:
6306       case OMPC_private:
6307       case OMPC_firstprivate:
6308       case OMPC_lastprivate:
6309       case OMPC_shared:
6310       case OMPC_reduction:
6311       case OMPC_task_reduction:
6312       case OMPC_in_reduction:
6313       case OMPC_linear:
6314       case OMPC_aligned:
6315       case OMPC_copyin:
6316       case OMPC_copyprivate:
6317       case OMPC_nowait:
6318       case OMPC_untied:
6319       case OMPC_mergeable:
6320       case OMPC_allocate:
6321       case OMPC_read:
6322       case OMPC_write:
6323       case OMPC_update:
6324       case OMPC_capture:
6325       case OMPC_seq_cst:
6326       case OMPC_acq_rel:
6327       case OMPC_acquire:
6328       case OMPC_release:
6329       case OMPC_relaxed:
6330       case OMPC_depend:
6331       case OMPC_threads:
6332       case OMPC_simd:
6333       case OMPC_map:
6334       case OMPC_nogroup:
6335       case OMPC_defaultmap:
6336       case OMPC_to:
6337       case OMPC_from:
6338       case OMPC_use_device_ptr:
6339       case OMPC_use_device_addr:
6340       case OMPC_is_device_ptr:
6341       case OMPC_nontemporal:
6342       case OMPC_order:
6343       case OMPC_destroy:
6344       case OMPC_inclusive:
6345       case OMPC_exclusive:
6346       case OMPC_uses_allocators:
6347       case OMPC_affinity:
6348         continue;
6349       case OMPC_allocator:
6350       case OMPC_flush:
6351       case OMPC_depobj:
6352       case OMPC_threadprivate:
6353       case OMPC_uniform:
6354       case OMPC_unknown:
6355       case OMPC_unified_address:
6356       case OMPC_unified_shared_memory:
6357       case OMPC_reverse_offload:
6358       case OMPC_dynamic_allocators:
6359       case OMPC_atomic_default_mem_order:
6360       case OMPC_device_type:
6361       case OMPC_match:
6362       case OMPC_when:
6363       default:
6364         llvm_unreachable("Unexpected clause");
6365       }
6366       for (Stmt *CC : C->children()) {
6367         if (CC)
6368           DSAChecker.Visit(CC);
6369       }
6370     }
6371     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6372       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6373   }
6374   for (const auto &P : VarsWithInheritedDSA) {
6375     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6376       continue;
6377     ErrorFound = true;
6378     if (DSAStack->getDefaultDSA() == DSA_none ||
6379         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6380       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6381           << P.first << P.second->getSourceRange();
6382       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6383     } else if (getLangOpts().OpenMP >= 50) {
6384       Diag(P.second->getExprLoc(),
6385            diag::err_omp_defaultmap_no_attr_for_variable)
6386           << P.first << P.second->getSourceRange();
6387       Diag(DSAStack->getDefaultDSALocation(),
6388            diag::note_omp_defaultmap_attr_none);
6389     }
6390   }
6391 
6392   if (!AllowedNameModifiers.empty())
6393     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6394                  ErrorFound;
6395 
6396   if (ErrorFound)
6397     return StmtError();
6398 
6399   if (!CurContext->isDependentContext() &&
6400       isOpenMPTargetExecutionDirective(Kind) &&
6401       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6402         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6403         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6404         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6405     // Register target to DSA Stack.
6406     DSAStack->addTargetDirLocation(StartLoc);
6407   }
6408 
6409   return Res;
6410 }
6411 
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)6412 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6413     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6414     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6415     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6416     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6417   assert(Aligneds.size() == Alignments.size());
6418   assert(Linears.size() == LinModifiers.size());
6419   assert(Linears.size() == Steps.size());
6420   if (!DG || DG.get().isNull())
6421     return DeclGroupPtrTy();
6422 
6423   const int SimdId = 0;
6424   if (!DG.get().isSingleDecl()) {
6425     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6426         << SimdId;
6427     return DG;
6428   }
6429   Decl *ADecl = DG.get().getSingleDecl();
6430   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6431     ADecl = FTD->getTemplatedDecl();
6432 
6433   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6434   if (!FD) {
6435     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6436     return DeclGroupPtrTy();
6437   }
6438 
6439   // OpenMP [2.8.2, declare simd construct, Description]
6440   // The parameter of the simdlen clause must be a constant positive integer
6441   // expression.
6442   ExprResult SL;
6443   if (Simdlen)
6444     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6445   // OpenMP [2.8.2, declare simd construct, Description]
6446   // The special this pointer can be used as if was one of the arguments to the
6447   // function in any of the linear, aligned, or uniform clauses.
6448   // The uniform clause declares one or more arguments to have an invariant
6449   // value for all concurrent invocations of the function in the execution of a
6450   // single SIMD loop.
6451   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6452   const Expr *UniformedLinearThis = nullptr;
6453   for (const Expr *E : Uniforms) {
6454     E = E->IgnoreParenImpCasts();
6455     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6456       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6457         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6458             FD->getParamDecl(PVD->getFunctionScopeIndex())
6459                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6460           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6461           continue;
6462         }
6463     if (isa<CXXThisExpr>(E)) {
6464       UniformedLinearThis = E;
6465       continue;
6466     }
6467     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6468         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6469   }
6470   // OpenMP [2.8.2, declare simd construct, Description]
6471   // The aligned clause declares that the object to which each list item points
6472   // is aligned to the number of bytes expressed in the optional parameter of
6473   // the aligned clause.
6474   // The special this pointer can be used as if was one of the arguments to the
6475   // function in any of the linear, aligned, or uniform clauses.
6476   // The type of list items appearing in the aligned clause must be array,
6477   // pointer, reference to array, or reference to pointer.
6478   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6479   const Expr *AlignedThis = nullptr;
6480   for (const Expr *E : Aligneds) {
6481     E = E->IgnoreParenImpCasts();
6482     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6483       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6484         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6485         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6486             FD->getParamDecl(PVD->getFunctionScopeIndex())
6487                     ->getCanonicalDecl() == CanonPVD) {
6488           // OpenMP  [2.8.1, simd construct, Restrictions]
6489           // A list-item cannot appear in more than one aligned clause.
6490           if (AlignedArgs.count(CanonPVD) > 0) {
6491             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6492                 << 1 << getOpenMPClauseName(OMPC_aligned)
6493                 << E->getSourceRange();
6494             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6495                  diag::note_omp_explicit_dsa)
6496                 << getOpenMPClauseName(OMPC_aligned);
6497             continue;
6498           }
6499           AlignedArgs[CanonPVD] = E;
6500           QualType QTy = PVD->getType()
6501                              .getNonReferenceType()
6502                              .getUnqualifiedType()
6503                              .getCanonicalType();
6504           const Type *Ty = QTy.getTypePtrOrNull();
6505           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6506             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6507                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6508             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6509           }
6510           continue;
6511         }
6512       }
6513     if (isa<CXXThisExpr>(E)) {
6514       if (AlignedThis) {
6515         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6516             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6517         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6518             << getOpenMPClauseName(OMPC_aligned);
6519       }
6520       AlignedThis = E;
6521       continue;
6522     }
6523     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6524         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6525   }
6526   // The optional parameter of the aligned clause, alignment, must be a constant
6527   // positive integer expression. If no optional parameter is specified,
6528   // implementation-defined default alignments for SIMD instructions on the
6529   // target platforms are assumed.
6530   SmallVector<const Expr *, 4> NewAligns;
6531   for (Expr *E : Alignments) {
6532     ExprResult Align;
6533     if (E)
6534       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6535     NewAligns.push_back(Align.get());
6536   }
6537   // OpenMP [2.8.2, declare simd construct, Description]
6538   // The linear clause declares one or more list items to be private to a SIMD
6539   // lane and to have a linear relationship with respect to the iteration space
6540   // of a loop.
6541   // The special this pointer can be used as if was one of the arguments to the
6542   // function in any of the linear, aligned, or uniform clauses.
6543   // When a linear-step expression is specified in a linear clause it must be
6544   // either a constant integer expression or an integer-typed parameter that is
6545   // specified in a uniform clause on the directive.
6546   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6547   const bool IsUniformedThis = UniformedLinearThis != nullptr;
6548   auto MI = LinModifiers.begin();
6549   for (const Expr *E : Linears) {
6550     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6551     ++MI;
6552     E = E->IgnoreParenImpCasts();
6553     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6554       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6555         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6556         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6557             FD->getParamDecl(PVD->getFunctionScopeIndex())
6558                     ->getCanonicalDecl() == CanonPVD) {
6559           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
6560           // A list-item cannot appear in more than one linear clause.
6561           if (LinearArgs.count(CanonPVD) > 0) {
6562             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6563                 << getOpenMPClauseName(OMPC_linear)
6564                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6565             Diag(LinearArgs[CanonPVD]->getExprLoc(),
6566                  diag::note_omp_explicit_dsa)
6567                 << getOpenMPClauseName(OMPC_linear);
6568             continue;
6569           }
6570           // Each argument can appear in at most one uniform or linear clause.
6571           if (UniformedArgs.count(CanonPVD) > 0) {
6572             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6573                 << getOpenMPClauseName(OMPC_linear)
6574                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6575             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6576                  diag::note_omp_explicit_dsa)
6577                 << getOpenMPClauseName(OMPC_uniform);
6578             continue;
6579           }
6580           LinearArgs[CanonPVD] = E;
6581           if (E->isValueDependent() || E->isTypeDependent() ||
6582               E->isInstantiationDependent() ||
6583               E->containsUnexpandedParameterPack())
6584             continue;
6585           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6586                                       PVD->getOriginalType(),
6587                                       /*IsDeclareSimd=*/true);
6588           continue;
6589         }
6590       }
6591     if (isa<CXXThisExpr>(E)) {
6592       if (UniformedLinearThis) {
6593         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6594             << getOpenMPClauseName(OMPC_linear)
6595             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6596             << E->getSourceRange();
6597         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6598             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6599                                                    : OMPC_linear);
6600         continue;
6601       }
6602       UniformedLinearThis = E;
6603       if (E->isValueDependent() || E->isTypeDependent() ||
6604           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6605         continue;
6606       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6607                                   E->getType(), /*IsDeclareSimd=*/true);
6608       continue;
6609     }
6610     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6611         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6612   }
6613   Expr *Step = nullptr;
6614   Expr *NewStep = nullptr;
6615   SmallVector<Expr *, 4> NewSteps;
6616   for (Expr *E : Steps) {
6617     // Skip the same step expression, it was checked already.
6618     if (Step == E || !E) {
6619       NewSteps.push_back(E ? NewStep : nullptr);
6620       continue;
6621     }
6622     Step = E;
6623     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6624       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6625         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6626         if (UniformedArgs.count(CanonPVD) == 0) {
6627           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6628               << Step->getSourceRange();
6629         } else if (E->isValueDependent() || E->isTypeDependent() ||
6630                    E->isInstantiationDependent() ||
6631                    E->containsUnexpandedParameterPack() ||
6632                    CanonPVD->getType()->hasIntegerRepresentation()) {
6633           NewSteps.push_back(Step);
6634         } else {
6635           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6636               << Step->getSourceRange();
6637         }
6638         continue;
6639       }
6640     NewStep = Step;
6641     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6642         !Step->isInstantiationDependent() &&
6643         !Step->containsUnexpandedParameterPack()) {
6644       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6645                     .get();
6646       if (NewStep)
6647         NewStep =
6648             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6649     }
6650     NewSteps.push_back(NewStep);
6651   }
6652   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6653       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6654       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6655       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6656       const_cast<Expr **>(Linears.data()), Linears.size(),
6657       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6658       NewSteps.data(), NewSteps.size(), SR);
6659   ADecl->addAttr(NewAttr);
6660   return DG;
6661 }
6662 
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)6663 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6664                          QualType NewType) {
6665   assert(NewType->isFunctionProtoType() &&
6666          "Expected function type with prototype.");
6667   assert(FD->getType()->isFunctionNoProtoType() &&
6668          "Expected function with type with no prototype.");
6669   assert(FDWithProto->getType()->isFunctionProtoType() &&
6670          "Expected function with prototype.");
6671   // Synthesize parameters with the same types.
6672   FD->setType(NewType);
6673   SmallVector<ParmVarDecl *, 16> Params;
6674   for (const ParmVarDecl *P : FDWithProto->parameters()) {
6675     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6676                                       SourceLocation(), nullptr, P->getType(),
6677                                       /*TInfo=*/nullptr, SC_None, nullptr);
6678     Param->setScopeInfo(0, Params.size());
6679     Param->setImplicit();
6680     Params.push_back(Param);
6681   }
6682 
6683   FD->setParams(Params);
6684 }
6685 
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)6686 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6687   if (D->isInvalidDecl())
6688     return;
6689   FunctionDecl *FD = nullptr;
6690   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6691     FD = UTemplDecl->getTemplatedDecl();
6692   else
6693     FD = cast<FunctionDecl>(D);
6694   assert(FD && "Expected a function declaration!");
6695 
6696   // If we are instantiating templates we do *not* apply scoped assumptions but
6697   // only global ones. We apply scoped assumption to the template definition
6698   // though.
6699   if (!inTemplateInstantiation()) {
6700     for (AssumptionAttr *AA : OMPAssumeScoped)
6701       FD->addAttr(AA);
6702   }
6703   for (AssumptionAttr *AA : OMPAssumeGlobal)
6704     FD->addAttr(AA);
6705 }
6706 
OMPDeclareVariantScope(OMPTraitInfo & TI)6707 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6708     : TI(&TI), NameSuffix(TI.getMangledName()) {}
6709 
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)6710 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6711     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6712     SmallVectorImpl<FunctionDecl *> &Bases) {
6713   if (!D.getIdentifier())
6714     return;
6715 
6716   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6717 
6718   // Template specialization is an extension, check if we do it.
6719   bool IsTemplated = !TemplateParamLists.empty();
6720   if (IsTemplated &
6721       !DVScope.TI->isExtensionActive(
6722           llvm::omp::TraitProperty::implementation_extension_allow_templates))
6723     return;
6724 
6725   IdentifierInfo *BaseII = D.getIdentifier();
6726   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6727                       LookupOrdinaryName);
6728   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6729 
6730   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6731   QualType FType = TInfo->getType();
6732 
6733   bool IsConstexpr =
6734       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6735   bool IsConsteval =
6736       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6737 
6738   for (auto *Candidate : Lookup) {
6739     auto *CandidateDecl = Candidate->getUnderlyingDecl();
6740     FunctionDecl *UDecl = nullptr;
6741     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6742       UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6743     else if (!IsTemplated)
6744       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6745     if (!UDecl)
6746       continue;
6747 
6748     // Don't specialize constexpr/consteval functions with
6749     // non-constexpr/consteval functions.
6750     if (UDecl->isConstexpr() && !IsConstexpr)
6751       continue;
6752     if (UDecl->isConsteval() && !IsConsteval)
6753       continue;
6754 
6755     QualType UDeclTy = UDecl->getType();
6756     if (!UDeclTy->isDependentType()) {
6757       QualType NewType = Context.mergeFunctionTypes(
6758           FType, UDeclTy, /* OfBlockPointer */ false,
6759           /* Unqualified */ false, /* AllowCXX */ true);
6760       if (NewType.isNull())
6761         continue;
6762     }
6763 
6764     // Found a base!
6765     Bases.push_back(UDecl);
6766   }
6767 
6768   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6769       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6770   // If no base was found we create a declaration that we use as base.
6771   if (Bases.empty() && UseImplicitBase) {
6772     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6773     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6774     BaseD->setImplicit(true);
6775     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6776       Bases.push_back(BaseTemplD->getTemplatedDecl());
6777     else
6778       Bases.push_back(cast<FunctionDecl>(BaseD));
6779   }
6780 
6781   std::string MangledName;
6782   MangledName += D.getIdentifier()->getName();
6783   MangledName += getOpenMPVariantManglingSeparatorStr();
6784   MangledName += DVScope.NameSuffix;
6785   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6786 
6787   VariantII.setMangledOpenMPVariantName(true);
6788   D.SetIdentifier(&VariantII, D.getBeginLoc());
6789 }
6790 
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)6791 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6792     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6793   // Do not mark function as is used to prevent its emission if this is the
6794   // only place where it is used.
6795   EnterExpressionEvaluationContext Unevaluated(
6796       *this, Sema::ExpressionEvaluationContext::Unevaluated);
6797 
6798   FunctionDecl *FD = nullptr;
6799   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6800     FD = UTemplDecl->getTemplatedDecl();
6801   else
6802     FD = cast<FunctionDecl>(D);
6803   auto *VariantFuncRef = DeclRefExpr::Create(
6804       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6805       /* RefersToEnclosingVariableOrCapture */ false,
6806       /* NameLoc */ FD->getLocation(), FD->getType(),
6807       ExprValueKind::VK_PRValue);
6808 
6809   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6810   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6811       Context, VariantFuncRef, DVScope.TI);
6812   for (FunctionDecl *BaseFD : Bases)
6813     BaseFD->addAttr(OMPDeclareVariantA);
6814 }
6815 
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)6816 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6817                                  SourceLocation LParenLoc,
6818                                  MultiExprArg ArgExprs,
6819                                  SourceLocation RParenLoc, Expr *ExecConfig) {
6820   // The common case is a regular call we do not want to specialize at all. Try
6821   // to make that case fast by bailing early.
6822   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6823   if (!CE)
6824     return Call;
6825 
6826   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6827   if (!CalleeFnDecl)
6828     return Call;
6829 
6830   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6831     return Call;
6832 
6833   ASTContext &Context = getASTContext();
6834   std::function<void(StringRef)> DiagUnknownTrait = [this,
6835                                                      CE](StringRef ISATrait) {
6836     // TODO Track the selector locations in a way that is accessible here to
6837     // improve the diagnostic location.
6838     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6839         << ISATrait;
6840   };
6841   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6842                           getCurFunctionDecl(), DSAStack->getConstructTraits());
6843 
6844   QualType CalleeFnType = CalleeFnDecl->getType();
6845 
6846   SmallVector<Expr *, 4> Exprs;
6847   SmallVector<VariantMatchInfo, 4> VMIs;
6848   while (CalleeFnDecl) {
6849     for (OMPDeclareVariantAttr *A :
6850          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6851       Expr *VariantRef = A->getVariantFuncRef();
6852 
6853       VariantMatchInfo VMI;
6854       OMPTraitInfo &TI = A->getTraitInfo();
6855       TI.getAsVariantMatchInfo(Context, VMI);
6856       if (!isVariantApplicableInContext(VMI, OMPCtx,
6857                                         /* DeviceSetOnly */ false))
6858         continue;
6859 
6860       VMIs.push_back(VMI);
6861       Exprs.push_back(VariantRef);
6862     }
6863 
6864     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6865   }
6866 
6867   ExprResult NewCall;
6868   do {
6869     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6870     if (BestIdx < 0)
6871       return Call;
6872     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6873     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6874 
6875     {
6876       // Try to build a (member) call expression for the current best applicable
6877       // variant expression. We allow this to fail in which case we continue
6878       // with the next best variant expression. The fail case is part of the
6879       // implementation defined behavior in the OpenMP standard when it talks
6880       // about what differences in the function prototypes: "Any differences
6881       // that the specific OpenMP context requires in the prototype of the
6882       // variant from the base function prototype are implementation defined."
6883       // This wording is there to allow the specialized variant to have a
6884       // different type than the base function. This is intended and OK but if
6885       // we cannot create a call the difference is not in the "implementation
6886       // defined range" we allow.
6887       Sema::TentativeAnalysisScope Trap(*this);
6888 
6889       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6890         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6891         BestExpr = MemberExpr::CreateImplicit(
6892             Context, MemberCall->getImplicitObjectArgument(),
6893             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6894             MemberCall->getValueKind(), MemberCall->getObjectKind());
6895       }
6896       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6897                               ExecConfig);
6898       if (NewCall.isUsable()) {
6899         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6900           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6901           QualType NewType = Context.mergeFunctionTypes(
6902               CalleeFnType, NewCalleeFnDecl->getType(),
6903               /* OfBlockPointer */ false,
6904               /* Unqualified */ false, /* AllowCXX */ true);
6905           if (!NewType.isNull())
6906             break;
6907           // Don't use the call if the function type was not compatible.
6908           NewCall = nullptr;
6909         }
6910       }
6911     }
6912 
6913     VMIs.erase(VMIs.begin() + BestIdx);
6914     Exprs.erase(Exprs.begin() + BestIdx);
6915   } while (!VMIs.empty());
6916 
6917   if (!NewCall.isUsable())
6918     return Call;
6919   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6920 }
6921 
6922 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6923 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6924                                         Expr *VariantRef, OMPTraitInfo &TI,
6925                                         SourceRange SR) {
6926   if (!DG || DG.get().isNull())
6927     return None;
6928 
6929   const int VariantId = 1;
6930   // Must be applied only to single decl.
6931   if (!DG.get().isSingleDecl()) {
6932     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6933         << VariantId << SR;
6934     return None;
6935   }
6936   Decl *ADecl = DG.get().getSingleDecl();
6937   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6938     ADecl = FTD->getTemplatedDecl();
6939 
6940   // Decl must be a function.
6941   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6942   if (!FD) {
6943     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6944         << VariantId << SR;
6945     return None;
6946   }
6947 
6948   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6949     return FD->hasAttrs() &&
6950            (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6951             FD->hasAttr<TargetAttr>());
6952   };
6953   // OpenMP is not compatible with CPU-specific attributes.
6954   if (HasMultiVersionAttributes(FD)) {
6955     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6956         << SR;
6957     return None;
6958   }
6959 
6960   // Allow #pragma omp declare variant only if the function is not used.
6961   if (FD->isUsed(false))
6962     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6963         << FD->getLocation();
6964 
6965   // Check if the function was emitted already.
6966   const FunctionDecl *Definition;
6967   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6968       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6969     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6970         << FD->getLocation();
6971 
6972   // The VariantRef must point to function.
6973   if (!VariantRef) {
6974     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6975     return None;
6976   }
6977 
6978   auto ShouldDelayChecks = [](Expr *&E, bool) {
6979     return E && (E->isTypeDependent() || E->isValueDependent() ||
6980                  E->containsUnexpandedParameterPack() ||
6981                  E->isInstantiationDependent());
6982   };
6983   // Do not check templates, wait until instantiation.
6984   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6985       TI.anyScoreOrCondition(ShouldDelayChecks))
6986     return std::make_pair(FD, VariantRef);
6987 
6988   // Deal with non-constant score and user condition expressions.
6989   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6990                                                      bool IsScore) -> bool {
6991     if (!E || E->isIntegerConstantExpr(Context))
6992       return false;
6993 
6994     if (IsScore) {
6995       // We warn on non-constant scores and pretend they were not present.
6996       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6997           << E;
6998       E = nullptr;
6999     } else {
7000       // We could replace a non-constant user condition with "false" but we
7001       // will soon need to handle these anyway for the dynamic version of
7002       // OpenMP context selectors.
7003       Diag(E->getExprLoc(),
7004            diag::err_omp_declare_variant_user_condition_not_constant)
7005           << E;
7006     }
7007     return true;
7008   };
7009   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7010     return None;
7011 
7012   // Convert VariantRef expression to the type of the original function to
7013   // resolve possible conflicts.
7014   ExprResult VariantRefCast = VariantRef;
7015   if (LangOpts.CPlusPlus) {
7016     QualType FnPtrType;
7017     auto *Method = dyn_cast<CXXMethodDecl>(FD);
7018     if (Method && !Method->isStatic()) {
7019       const Type *ClassType =
7020           Context.getTypeDeclType(Method->getParent()).getTypePtr();
7021       FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
7022       ExprResult ER;
7023       {
7024         // Build adrr_of unary op to correctly handle type checks for member
7025         // functions.
7026         Sema::TentativeAnalysisScope Trap(*this);
7027         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7028                                   VariantRef);
7029       }
7030       if (!ER.isUsable()) {
7031         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7032             << VariantId << VariantRef->getSourceRange();
7033         return None;
7034       }
7035       VariantRef = ER.get();
7036     } else {
7037       FnPtrType = Context.getPointerType(FD->getType());
7038     }
7039     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7040     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7041       ImplicitConversionSequence ICS = TryImplicitConversion(
7042           VariantRef, FnPtrType.getUnqualifiedType(),
7043           /*SuppressUserConversions=*/false, AllowedExplicit::None,
7044           /*InOverloadResolution=*/false,
7045           /*CStyle=*/false,
7046           /*AllowObjCWritebackConversion=*/false);
7047       if (ICS.isFailure()) {
7048         Diag(VariantRef->getExprLoc(),
7049              diag::err_omp_declare_variant_incompat_types)
7050             << VariantRef->getType()
7051             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7052             << VariantRef->getSourceRange();
7053         return None;
7054       }
7055       VariantRefCast = PerformImplicitConversion(
7056           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7057       if (!VariantRefCast.isUsable())
7058         return None;
7059     }
7060     // Drop previously built artificial addr_of unary op for member functions.
7061     if (Method && !Method->isStatic()) {
7062       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7063       if (auto *UO = dyn_cast<UnaryOperator>(
7064               PossibleAddrOfVariantRef->IgnoreImplicit()))
7065         VariantRefCast = UO->getSubExpr();
7066     }
7067   }
7068 
7069   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7070   if (!ER.isUsable() ||
7071       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7072     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7073         << VariantId << VariantRef->getSourceRange();
7074     return None;
7075   }
7076 
7077   // The VariantRef must point to function.
7078   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7079   if (!DRE) {
7080     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7081         << VariantId << VariantRef->getSourceRange();
7082     return None;
7083   }
7084   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7085   if (!NewFD) {
7086     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7087         << VariantId << VariantRef->getSourceRange();
7088     return None;
7089   }
7090 
7091   // Check if function types are compatible in C.
7092   if (!LangOpts.CPlusPlus) {
7093     QualType NewType =
7094         Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
7095     if (NewType.isNull()) {
7096       Diag(VariantRef->getExprLoc(),
7097            diag::err_omp_declare_variant_incompat_types)
7098           << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
7099       return None;
7100     }
7101     if (NewType->isFunctionProtoType()) {
7102       if (FD->getType()->isFunctionNoProtoType())
7103         setPrototype(*this, FD, NewFD, NewType);
7104       else if (NewFD->getType()->isFunctionNoProtoType())
7105         setPrototype(*this, NewFD, FD, NewType);
7106     }
7107   }
7108 
7109   // Check if variant function is not marked with declare variant directive.
7110   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7111     Diag(VariantRef->getExprLoc(),
7112          diag::warn_omp_declare_variant_marked_as_declare_variant)
7113         << VariantRef->getSourceRange();
7114     SourceRange SR =
7115         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7116     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7117     return None;
7118   }
7119 
7120   enum DoesntSupport {
7121     VirtFuncs = 1,
7122     Constructors = 3,
7123     Destructors = 4,
7124     DeletedFuncs = 5,
7125     DefaultedFuncs = 6,
7126     ConstexprFuncs = 7,
7127     ConstevalFuncs = 8,
7128   };
7129   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7130     if (CXXFD->isVirtual()) {
7131       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7132           << VirtFuncs;
7133       return None;
7134     }
7135 
7136     if (isa<CXXConstructorDecl>(FD)) {
7137       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7138           << Constructors;
7139       return None;
7140     }
7141 
7142     if (isa<CXXDestructorDecl>(FD)) {
7143       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7144           << Destructors;
7145       return None;
7146     }
7147   }
7148 
7149   if (FD->isDeleted()) {
7150     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7151         << DeletedFuncs;
7152     return None;
7153   }
7154 
7155   if (FD->isDefaulted()) {
7156     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7157         << DefaultedFuncs;
7158     return None;
7159   }
7160 
7161   if (FD->isConstexpr()) {
7162     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7163         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7164     return None;
7165   }
7166 
7167   // Check general compatibility.
7168   if (areMultiversionVariantFunctionsCompatible(
7169           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7170           PartialDiagnosticAt(SourceLocation(),
7171                               PartialDiagnostic::NullDiagnostic()),
7172           PartialDiagnosticAt(
7173               VariantRef->getExprLoc(),
7174               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7175           PartialDiagnosticAt(VariantRef->getExprLoc(),
7176                               PDiag(diag::err_omp_declare_variant_diff)
7177                                   << FD->getLocation()),
7178           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7179           /*CLinkageMayDiffer=*/true))
7180     return None;
7181   return std::make_pair(FD, cast<Expr>(DRE));
7182 }
7183 
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)7184 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7185                                               Expr *VariantRef,
7186                                               OMPTraitInfo &TI,
7187                                               SourceRange SR) {
7188   auto *NewAttr =
7189       OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7190   FD->addAttr(NewAttr);
7191 }
7192 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7193 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7194                                               Stmt *AStmt,
7195                                               SourceLocation StartLoc,
7196                                               SourceLocation EndLoc) {
7197   if (!AStmt)
7198     return StmtError();
7199 
7200   auto *CS = cast<CapturedStmt>(AStmt);
7201   // 1.2.2 OpenMP Language Terminology
7202   // Structured block - An executable statement with a single entry at the
7203   // top and a single exit at the bottom.
7204   // The point of exit cannot be a branch out of the structured block.
7205   // longjmp() and throw() must not violate the entry/exit criteria.
7206   CS->getCapturedDecl()->setNothrow();
7207 
7208   setFunctionHasBranchProtectedScope();
7209 
7210   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7211                                       DSAStack->getTaskgroupReductionRef(),
7212                                       DSAStack->isCancelRegion());
7213 }
7214 
7215 namespace {
7216 /// Iteration space of a single for loop.
7217 struct LoopIterationSpace final {
7218   /// True if the condition operator is the strict compare operator (<, > or
7219   /// !=).
7220   bool IsStrictCompare = false;
7221   /// Condition of the loop.
7222   Expr *PreCond = nullptr;
7223   /// This expression calculates the number of iterations in the loop.
7224   /// It is always possible to calculate it before starting the loop.
7225   Expr *NumIterations = nullptr;
7226   /// The loop counter variable.
7227   Expr *CounterVar = nullptr;
7228   /// Private loop counter variable.
7229   Expr *PrivateCounterVar = nullptr;
7230   /// This is initializer for the initial value of #CounterVar.
7231   Expr *CounterInit = nullptr;
7232   /// This is step for the #CounterVar used to generate its update:
7233   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7234   Expr *CounterStep = nullptr;
7235   /// Should step be subtracted?
7236   bool Subtract = false;
7237   /// Source range of the loop init.
7238   SourceRange InitSrcRange;
7239   /// Source range of the loop condition.
7240   SourceRange CondSrcRange;
7241   /// Source range of the loop increment.
7242   SourceRange IncSrcRange;
7243   /// Minimum value that can have the loop control variable. Used to support
7244   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7245   /// since only such variables can be used in non-loop invariant expressions.
7246   Expr *MinValue = nullptr;
7247   /// Maximum value that can have the loop control variable. Used to support
7248   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7249   /// since only such variables can be used in non-loop invariant expressions.
7250   Expr *MaxValue = nullptr;
7251   /// true, if the lower bound depends on the outer loop control var.
7252   bool IsNonRectangularLB = false;
7253   /// true, if the upper bound depends on the outer loop control var.
7254   bool IsNonRectangularUB = false;
7255   /// Index of the loop this loop depends on and forms non-rectangular loop
7256   /// nest.
7257   unsigned LoopDependentIdx = 0;
7258   /// Final condition for the non-rectangular loop nest support. It is used to
7259   /// check that the number of iterations for this particular counter must be
7260   /// finished.
7261   Expr *FinalCondition = nullptr;
7262 };
7263 
7264 /// Helper class for checking canonical form of the OpenMP loops and
7265 /// extracting iteration space of each loop in the loop nest, that will be used
7266 /// for IR generation.
7267 class OpenMPIterationSpaceChecker {
7268   /// Reference to Sema.
7269   Sema &SemaRef;
7270   /// Does the loop associated directive support non-rectangular loops?
7271   bool SupportsNonRectangular;
7272   /// Data-sharing stack.
7273   DSAStackTy &Stack;
7274   /// A location for diagnostics (when there is no some better location).
7275   SourceLocation DefaultLoc;
7276   /// A location for diagnostics (when increment is not compatible).
7277   SourceLocation ConditionLoc;
7278   /// A source location for referring to loop init later.
7279   SourceRange InitSrcRange;
7280   /// A source location for referring to condition later.
7281   SourceRange ConditionSrcRange;
7282   /// A source location for referring to increment later.
7283   SourceRange IncrementSrcRange;
7284   /// Loop variable.
7285   ValueDecl *LCDecl = nullptr;
7286   /// Reference to loop variable.
7287   Expr *LCRef = nullptr;
7288   /// Lower bound (initializer for the var).
7289   Expr *LB = nullptr;
7290   /// Upper bound.
7291   Expr *UB = nullptr;
7292   /// Loop step (increment).
7293   Expr *Step = nullptr;
7294   /// This flag is true when condition is one of:
7295   ///   Var <  UB
7296   ///   Var <= UB
7297   ///   UB  >  Var
7298   ///   UB  >= Var
7299   /// This will have no value when the condition is !=
7300   llvm::Optional<bool> TestIsLessOp;
7301   /// This flag is true when condition is strict ( < or > ).
7302   bool TestIsStrictOp = false;
7303   /// This flag is true when step is subtracted on each iteration.
7304   bool SubtractStep = false;
7305   /// The outer loop counter this loop depends on (if any).
7306   const ValueDecl *DepDecl = nullptr;
7307   /// Contains number of loop (starts from 1) on which loop counter init
7308   /// expression of this loop depends on.
7309   Optional<unsigned> InitDependOnLC;
7310   /// Contains number of loop (starts from 1) on which loop counter condition
7311   /// expression of this loop depends on.
7312   Optional<unsigned> CondDependOnLC;
7313   /// Checks if the provide statement depends on the loop counter.
7314   Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7315   /// Original condition required for checking of the exit condition for
7316   /// non-rectangular loop.
7317   Expr *Condition = nullptr;
7318 
7319 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,bool SupportsNonRectangular,DSAStackTy & Stack,SourceLocation DefaultLoc)7320   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7321                               DSAStackTy &Stack, SourceLocation DefaultLoc)
7322       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7323         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7324   /// Check init-expr for canonical loop form and save loop counter
7325   /// variable - #Var and its initialization value - #LB.
7326   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7327   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7328   /// for less/greater and for strict/non-strict comparison.
7329   bool checkAndSetCond(Expr *S);
7330   /// Check incr-expr for canonical loop form and return true if it
7331   /// does not conform, otherwise save loop step (#Step).
7332   bool checkAndSetInc(Expr *S);
7333   /// Return the loop counter variable.
getLoopDecl() const7334   ValueDecl *getLoopDecl() const { return LCDecl; }
7335   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const7336   Expr *getLoopDeclRefExpr() const { return LCRef; }
7337   /// Source range of the loop init.
getInitSrcRange() const7338   SourceRange getInitSrcRange() const { return InitSrcRange; }
7339   /// Source range of the loop condition.
getConditionSrcRange() const7340   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7341   /// Source range of the loop increment.
getIncrementSrcRange() const7342   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7343   /// True if the step should be subtracted.
shouldSubtractStep() const7344   bool shouldSubtractStep() const { return SubtractStep; }
7345   /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const7346   bool isStrictTestOp() const { return TestIsStrictOp; }
7347   /// Build the expression to calculate the number of iterations.
7348   Expr *buildNumIterations(
7349       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7350       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7351   /// Build the precondition expression for the loops.
7352   Expr *
7353   buildPreCond(Scope *S, Expr *Cond,
7354                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7355   /// Build reference expression to the counter be used for codegen.
7356   DeclRefExpr *
7357   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7358                   DSAStackTy &DSA) const;
7359   /// Build reference expression to the private counter be used for
7360   /// codegen.
7361   Expr *buildPrivateCounterVar() const;
7362   /// Build initialization of the counter be used for codegen.
7363   Expr *buildCounterInit() const;
7364   /// Build step of the counter be used for codegen.
7365   Expr *buildCounterStep() const;
7366   /// Build loop data with counter value for depend clauses in ordered
7367   /// directives.
7368   Expr *
7369   buildOrderedLoopData(Scope *S, Expr *Counter,
7370                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7371                        SourceLocation Loc, Expr *Inc = nullptr,
7372                        OverloadedOperatorKind OOK = OO_Amp);
7373   /// Builds the minimum value for the loop counter.
7374   std::pair<Expr *, Expr *> buildMinMaxValues(
7375       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7376   /// Builds final condition for the non-rectangular loops.
7377   Expr *buildFinalCondition(Scope *S) const;
7378   /// Return true if any expression is dependent.
7379   bool dependent() const;
7380   /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const7381   bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7382   /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const7383   bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7384   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const7385   unsigned getLoopDependentIdx() const {
7386     return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7387   }
7388 
7389 private:
7390   /// Check the right-hand side of an assignment in the increment
7391   /// expression.
7392   bool checkAndSetIncRHS(Expr *RHS);
7393   /// Helper to set loop counter variable and its initializer.
7394   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7395                       bool EmitDiags);
7396   /// Helper to set upper bound.
7397   bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7398              SourceRange SR, SourceLocation SL);
7399   /// Helper to set loop increment.
7400   bool setStep(Expr *NewStep, bool Subtract);
7401 };
7402 
dependent() const7403 bool OpenMPIterationSpaceChecker::dependent() const {
7404   if (!LCDecl) {
7405     assert(!LB && !UB && !Step);
7406     return false;
7407   }
7408   return LCDecl->getType()->isDependentType() ||
7409          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7410          (Step && Step->isValueDependent());
7411 }
7412 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)7413 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7414                                                  Expr *NewLCRefExpr,
7415                                                  Expr *NewLB, bool EmitDiags) {
7416   // State consistency checking to ensure correct usage.
7417   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7418          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7419   if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7420     return true;
7421   LCDecl = getCanonicalDecl(NewLCDecl);
7422   LCRef = NewLCRefExpr;
7423   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7424     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7425       if ((Ctor->isCopyOrMoveConstructor() ||
7426            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7427           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7428         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7429   LB = NewLB;
7430   if (EmitDiags)
7431     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7432   return false;
7433 }
7434 
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)7435 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7436                                         llvm::Optional<bool> LessOp,
7437                                         bool StrictOp, SourceRange SR,
7438                                         SourceLocation SL) {
7439   // State consistency checking to ensure correct usage.
7440   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7441          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7442   if (!NewUB || NewUB->containsErrors())
7443     return true;
7444   UB = NewUB;
7445   if (LessOp)
7446     TestIsLessOp = LessOp;
7447   TestIsStrictOp = StrictOp;
7448   ConditionSrcRange = SR;
7449   ConditionLoc = SL;
7450   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7451   return false;
7452 }
7453 
setStep(Expr * NewStep,bool Subtract)7454 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7455   // State consistency checking to ensure correct usage.
7456   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7457   if (!NewStep || NewStep->containsErrors())
7458     return true;
7459   if (!NewStep->isValueDependent()) {
7460     // Check that the step is integer expression.
7461     SourceLocation StepLoc = NewStep->getBeginLoc();
7462     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7463         StepLoc, getExprAsWritten(NewStep));
7464     if (Val.isInvalid())
7465       return true;
7466     NewStep = Val.get();
7467 
7468     // OpenMP [2.6, Canonical Loop Form, Restrictions]
7469     //  If test-expr is of form var relational-op b and relational-op is < or
7470     //  <= then incr-expr must cause var to increase on each iteration of the
7471     //  loop. If test-expr is of form var relational-op b and relational-op is
7472     //  > or >= then incr-expr must cause var to decrease on each iteration of
7473     //  the loop.
7474     //  If test-expr is of form b relational-op var and relational-op is < or
7475     //  <= then incr-expr must cause var to decrease on each iteration of the
7476     //  loop. If test-expr is of form b relational-op var and relational-op is
7477     //  > or >= then incr-expr must cause var to increase on each iteration of
7478     //  the loop.
7479     Optional<llvm::APSInt> Result =
7480         NewStep->getIntegerConstantExpr(SemaRef.Context);
7481     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7482     bool IsConstNeg =
7483         Result && Result->isSigned() && (Subtract != Result->isNegative());
7484     bool IsConstPos =
7485         Result && Result->isSigned() && (Subtract == Result->isNegative());
7486     bool IsConstZero = Result && !Result->getBoolValue();
7487 
7488     // != with increment is treated as <; != with decrement is treated as >
7489     if (!TestIsLessOp.hasValue())
7490       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7491     if (UB && (IsConstZero ||
7492                (TestIsLessOp.getValue() ?
7493                   (IsConstNeg || (IsUnsigned && Subtract)) :
7494                   (IsConstPos || (IsUnsigned && !Subtract))))) {
7495       SemaRef.Diag(NewStep->getExprLoc(),
7496                    diag::err_omp_loop_incr_not_compatible)
7497           << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7498       SemaRef.Diag(ConditionLoc,
7499                    diag::note_omp_loop_cond_requres_compatible_incr)
7500           << TestIsLessOp.getValue() << ConditionSrcRange;
7501       return true;
7502     }
7503     if (TestIsLessOp.getValue() == Subtract) {
7504       NewStep =
7505           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7506               .get();
7507       Subtract = !Subtract;
7508     }
7509   }
7510 
7511   Step = NewStep;
7512   SubtractStep = Subtract;
7513   return false;
7514 }
7515 
7516 namespace {
7517 /// Checker for the non-rectangular loops. Checks if the initializer or
7518 /// condition expression references loop counter variable.
7519 class LoopCounterRefChecker final
7520     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7521   Sema &SemaRef;
7522   DSAStackTy &Stack;
7523   const ValueDecl *CurLCDecl = nullptr;
7524   const ValueDecl *DepDecl = nullptr;
7525   const ValueDecl *PrevDepDecl = nullptr;
7526   bool IsInitializer = true;
7527   bool SupportsNonRectangular;
7528   unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)7529   bool checkDecl(const Expr *E, const ValueDecl *VD) {
7530     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7531       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7532           << (IsInitializer ? 0 : 1);
7533       return false;
7534     }
7535     const auto &&Data = Stack.isLoopControlVariable(VD);
7536     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7537     // The type of the loop iterator on which we depend may not have a random
7538     // access iterator type.
7539     if (Data.first && VD->getType()->isRecordType()) {
7540       SmallString<128> Name;
7541       llvm::raw_svector_ostream OS(Name);
7542       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7543                                /*Qualified=*/true);
7544       SemaRef.Diag(E->getExprLoc(),
7545                    diag::err_omp_wrong_dependency_iterator_type)
7546           << OS.str();
7547       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7548       return false;
7549     }
7550     if (Data.first && !SupportsNonRectangular) {
7551       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7552       return false;
7553     }
7554     if (Data.first &&
7555         (DepDecl || (PrevDepDecl &&
7556                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7557       if (!DepDecl && PrevDepDecl)
7558         DepDecl = PrevDepDecl;
7559       SmallString<128> Name;
7560       llvm::raw_svector_ostream OS(Name);
7561       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7562                                     /*Qualified=*/true);
7563       SemaRef.Diag(E->getExprLoc(),
7564                    diag::err_omp_invariant_or_linear_dependency)
7565           << OS.str();
7566       return false;
7567     }
7568     if (Data.first) {
7569       DepDecl = VD;
7570       BaseLoopId = Data.first;
7571     }
7572     return Data.first;
7573   }
7574 
7575 public:
VisitDeclRefExpr(const DeclRefExpr * E)7576   bool VisitDeclRefExpr(const DeclRefExpr *E) {
7577     const ValueDecl *VD = E->getDecl();
7578     if (isa<VarDecl>(VD))
7579       return checkDecl(E, VD);
7580     return false;
7581   }
VisitMemberExpr(const MemberExpr * E)7582   bool VisitMemberExpr(const MemberExpr *E) {
7583     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7584       const ValueDecl *VD = E->getMemberDecl();
7585       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7586         return checkDecl(E, VD);
7587     }
7588     return false;
7589   }
VisitStmt(const Stmt * S)7590   bool VisitStmt(const Stmt *S) {
7591     bool Res = false;
7592     for (const Stmt *Child : S->children())
7593       Res = (Child && Visit(Child)) || Res;
7594     return Res;
7595   }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr,bool SupportsNonRectangular=true)7596   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7597                                  const ValueDecl *CurLCDecl, bool IsInitializer,
7598                                  const ValueDecl *PrevDepDecl = nullptr,
7599                                  bool SupportsNonRectangular = true)
7600       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7601         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7602         SupportsNonRectangular(SupportsNonRectangular) {}
getBaseLoopId() const7603   unsigned getBaseLoopId() const {
7604     assert(CurLCDecl && "Expected loop dependency.");
7605     return BaseLoopId;
7606   }
getDepDecl() const7607   const ValueDecl *getDepDecl() const {
7608     assert(CurLCDecl && "Expected loop dependency.");
7609     return DepDecl;
7610   }
7611 };
7612 } // namespace
7613 
7614 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)7615 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7616                                                      bool IsInitializer) {
7617   // Check for the non-rectangular loops.
7618   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7619                                         DepDecl, SupportsNonRectangular);
7620   if (LoopStmtChecker.Visit(S)) {
7621     DepDecl = LoopStmtChecker.getDepDecl();
7622     return LoopStmtChecker.getBaseLoopId();
7623   }
7624   return llvm::None;
7625 }
7626 
checkAndSetInit(Stmt * S,bool EmitDiags)7627 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7628   // Check init-expr for canonical loop form and save loop counter
7629   // variable - #Var and its initialization value - #LB.
7630   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7631   //   var = lb
7632   //   integer-type var = lb
7633   //   random-access-iterator-type var = lb
7634   //   pointer-type var = lb
7635   //
7636   if (!S) {
7637     if (EmitDiags) {
7638       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7639     }
7640     return true;
7641   }
7642   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7643     if (!ExprTemp->cleanupsHaveSideEffects())
7644       S = ExprTemp->getSubExpr();
7645 
7646   InitSrcRange = S->getSourceRange();
7647   if (Expr *E = dyn_cast<Expr>(S))
7648     S = E->IgnoreParens();
7649   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7650     if (BO->getOpcode() == BO_Assign) {
7651       Expr *LHS = BO->getLHS()->IgnoreParens();
7652       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7653         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7654           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7655             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7656                                   EmitDiags);
7657         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7658       }
7659       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7660         if (ME->isArrow() &&
7661             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7662           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7663                                 EmitDiags);
7664       }
7665     }
7666   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7667     if (DS->isSingleDecl()) {
7668       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7669         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7670           // Accept non-canonical init form here but emit ext. warning.
7671           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7672             SemaRef.Diag(S->getBeginLoc(),
7673                          diag::ext_omp_loop_not_canonical_init)
7674                 << S->getSourceRange();
7675           return setLCDeclAndLB(
7676               Var,
7677               buildDeclRefExpr(SemaRef, Var,
7678                                Var->getType().getNonReferenceType(),
7679                                DS->getBeginLoc()),
7680               Var->getInit(), EmitDiags);
7681         }
7682       }
7683     }
7684   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7685     if (CE->getOperator() == OO_Equal) {
7686       Expr *LHS = CE->getArg(0);
7687       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7688         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7689           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7690             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7691                                   EmitDiags);
7692         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7693       }
7694       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7695         if (ME->isArrow() &&
7696             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7697           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7698                                 EmitDiags);
7699       }
7700     }
7701   }
7702 
7703   if (dependent() || SemaRef.CurContext->isDependentContext())
7704     return false;
7705   if (EmitDiags) {
7706     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7707         << S->getSourceRange();
7708   }
7709   return true;
7710 }
7711 
7712 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7713 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)7714 static const ValueDecl *getInitLCDecl(const Expr *E) {
7715   if (!E)
7716     return nullptr;
7717   E = getExprAsWritten(E);
7718   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7719     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7720       if ((Ctor->isCopyOrMoveConstructor() ||
7721            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7722           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7723         E = CE->getArg(0)->IgnoreParenImpCasts();
7724   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7725     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7726       return getCanonicalDecl(VD);
7727   }
7728   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7729     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7730       return getCanonicalDecl(ME->getMemberDecl());
7731   return nullptr;
7732 }
7733 
checkAndSetCond(Expr * S)7734 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7735   // Check test-expr for canonical form, save upper-bound UB, flags for
7736   // less/greater and for strict/non-strict comparison.
7737   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7738   //   var relational-op b
7739   //   b relational-op var
7740   //
7741   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7742   if (!S) {
7743     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7744         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7745     return true;
7746   }
7747   Condition = S;
7748   S = getExprAsWritten(S);
7749   SourceLocation CondLoc = S->getBeginLoc();
7750   auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7751                                BinaryOperatorKind Opcode, const Expr *LHS,
7752                                const Expr *RHS, SourceRange SR,
7753                                SourceLocation OpLoc) -> llvm::Optional<bool> {
7754     if (BinaryOperator::isRelationalOp(Opcode)) {
7755       if (getInitLCDecl(LHS) == LCDecl)
7756         return setUB(const_cast<Expr *>(RHS),
7757                      (Opcode == BO_LT || Opcode == BO_LE),
7758                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7759       if (getInitLCDecl(RHS) == LCDecl)
7760         return setUB(const_cast<Expr *>(LHS),
7761                      (Opcode == BO_GT || Opcode == BO_GE),
7762                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7763     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7764       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7765                    /*LessOp=*/llvm::None,
7766                    /*StrictOp=*/true, SR, OpLoc);
7767     }
7768     return llvm::None;
7769   };
7770   llvm::Optional<bool> Res;
7771   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7772     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7773     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7774                           RBO->getOperatorLoc());
7775   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7776     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7777                           BO->getSourceRange(), BO->getOperatorLoc());
7778   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7779     if (CE->getNumArgs() == 2) {
7780       Res = CheckAndSetCond(
7781           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7782           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7783     }
7784   }
7785   if (Res.hasValue())
7786     return *Res;
7787   if (dependent() || SemaRef.CurContext->isDependentContext())
7788     return false;
7789   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7790       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7791   return true;
7792 }
7793 
checkAndSetIncRHS(Expr * RHS)7794 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7795   // RHS of canonical loop form increment can be:
7796   //   var + incr
7797   //   incr + var
7798   //   var - incr
7799   //
7800   RHS = RHS->IgnoreParenImpCasts();
7801   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7802     if (BO->isAdditiveOp()) {
7803       bool IsAdd = BO->getOpcode() == BO_Add;
7804       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7805         return setStep(BO->getRHS(), !IsAdd);
7806       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7807         return setStep(BO->getLHS(), /*Subtract=*/false);
7808     }
7809   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7810     bool IsAdd = CE->getOperator() == OO_Plus;
7811     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7812       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7813         return setStep(CE->getArg(1), !IsAdd);
7814       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7815         return setStep(CE->getArg(0), /*Subtract=*/false);
7816     }
7817   }
7818   if (dependent() || SemaRef.CurContext->isDependentContext())
7819     return false;
7820   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7821       << RHS->getSourceRange() << LCDecl;
7822   return true;
7823 }
7824 
checkAndSetInc(Expr * S)7825 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7826   // Check incr-expr for canonical loop form and return true if it
7827   // does not conform.
7828   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7829   //   ++var
7830   //   var++
7831   //   --var
7832   //   var--
7833   //   var += incr
7834   //   var -= incr
7835   //   var = var + incr
7836   //   var = incr + var
7837   //   var = var - incr
7838   //
7839   if (!S) {
7840     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7841     return true;
7842   }
7843   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7844     if (!ExprTemp->cleanupsHaveSideEffects())
7845       S = ExprTemp->getSubExpr();
7846 
7847   IncrementSrcRange = S->getSourceRange();
7848   S = S->IgnoreParens();
7849   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7850     if (UO->isIncrementDecrementOp() &&
7851         getInitLCDecl(UO->getSubExpr()) == LCDecl)
7852       return setStep(SemaRef
7853                          .ActOnIntegerConstant(UO->getBeginLoc(),
7854                                                (UO->isDecrementOp() ? -1 : 1))
7855                          .get(),
7856                      /*Subtract=*/false);
7857   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7858     switch (BO->getOpcode()) {
7859     case BO_AddAssign:
7860     case BO_SubAssign:
7861       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7862         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7863       break;
7864     case BO_Assign:
7865       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7866         return checkAndSetIncRHS(BO->getRHS());
7867       break;
7868     default:
7869       break;
7870     }
7871   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7872     switch (CE->getOperator()) {
7873     case OO_PlusPlus:
7874     case OO_MinusMinus:
7875       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7876         return setStep(SemaRef
7877                            .ActOnIntegerConstant(
7878                                CE->getBeginLoc(),
7879                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7880                            .get(),
7881                        /*Subtract=*/false);
7882       break;
7883     case OO_PlusEqual:
7884     case OO_MinusEqual:
7885       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7886         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7887       break;
7888     case OO_Equal:
7889       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7890         return checkAndSetIncRHS(CE->getArg(1));
7891       break;
7892     default:
7893       break;
7894     }
7895   }
7896   if (dependent() || SemaRef.CurContext->isDependentContext())
7897     return false;
7898   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7899       << S->getSourceRange() << LCDecl;
7900   return true;
7901 }
7902 
7903 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7904 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7905                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7906   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7907     return Capture;
7908   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7909     return SemaRef.PerformImplicitConversion(
7910         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7911         /*AllowExplicit=*/true);
7912   auto I = Captures.find(Capture);
7913   if (I != Captures.end())
7914     return buildCapture(SemaRef, Capture, I->second);
7915   DeclRefExpr *Ref = nullptr;
7916   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7917   Captures[Capture] = Ref;
7918   return Res;
7919 }
7920 
7921 /// Calculate number of iterations, transforming to unsigned, if number of
7922 /// iterations may be larger than the original type.
7923 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)7924 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7925                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7926                   bool TestIsStrictOp, bool RoundToStep,
7927                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7928   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7929   if (!NewStep.isUsable())
7930     return nullptr;
7931   llvm::APSInt LRes, SRes;
7932   bool IsLowerConst = false, IsStepConst = false;
7933   if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7934     LRes = *Res;
7935     IsLowerConst = true;
7936   }
7937   if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7938     SRes = *Res;
7939     IsStepConst = true;
7940   }
7941   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7942                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
7943                           (TestIsStrictOp && LRes.isStrictlyPositive()));
7944   bool NeedToReorganize = false;
7945   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7946   if (!NoNeedToConvert && IsLowerConst &&
7947       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7948     NoNeedToConvert = true;
7949     if (RoundToStep) {
7950       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7951                         ? LRes.getBitWidth()
7952                         : SRes.getBitWidth();
7953       LRes = LRes.extend(BW + 1);
7954       LRes.setIsSigned(true);
7955       SRes = SRes.extend(BW + 1);
7956       SRes.setIsSigned(true);
7957       LRes -= SRes;
7958       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7959       LRes = LRes.trunc(BW);
7960     }
7961     if (TestIsStrictOp) {
7962       unsigned BW = LRes.getBitWidth();
7963       LRes = LRes.extend(BW + 1);
7964       LRes.setIsSigned(true);
7965       ++LRes;
7966       NoNeedToConvert =
7967           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7968       // truncate to the original bitwidth.
7969       LRes = LRes.trunc(BW);
7970     }
7971     NeedToReorganize = NoNeedToConvert;
7972   }
7973   llvm::APSInt URes;
7974   bool IsUpperConst = false;
7975   if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7976     URes = *Res;
7977     IsUpperConst = true;
7978   }
7979   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7980       (!RoundToStep || IsStepConst)) {
7981     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7982                                                           : URes.getBitWidth();
7983     LRes = LRes.extend(BW + 1);
7984     LRes.setIsSigned(true);
7985     URes = URes.extend(BW + 1);
7986     URes.setIsSigned(true);
7987     URes -= LRes;
7988     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7989     NeedToReorganize = NoNeedToConvert;
7990   }
7991   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7992   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7993   // unsigned.
7994   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7995       !LCTy->isDependentType() && LCTy->isIntegerType()) {
7996     QualType LowerTy = Lower->getType();
7997     QualType UpperTy = Upper->getType();
7998     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7999     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8000     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8001         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8002       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8003           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8004       Upper =
8005           SemaRef
8006               .PerformImplicitConversion(
8007                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8008                   CastType, Sema::AA_Converting)
8009               .get();
8010       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8011       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8012     }
8013   }
8014   if (!Lower || !Upper || NewStep.isInvalid())
8015     return nullptr;
8016 
8017   ExprResult Diff;
8018   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8019   // 1]).
8020   if (NeedToReorganize) {
8021     Diff = Lower;
8022 
8023     if (RoundToStep) {
8024       // Lower - Step
8025       Diff =
8026           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8027       if (!Diff.isUsable())
8028         return nullptr;
8029     }
8030 
8031     // Lower - Step [+ 1]
8032     if (TestIsStrictOp)
8033       Diff = SemaRef.BuildBinOp(
8034           S, DefaultLoc, BO_Add, Diff.get(),
8035           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8036     if (!Diff.isUsable())
8037       return nullptr;
8038 
8039     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8040     if (!Diff.isUsable())
8041       return nullptr;
8042 
8043     // Upper - (Lower - Step [+ 1]).
8044     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8045     if (!Diff.isUsable())
8046       return nullptr;
8047   } else {
8048     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8049 
8050     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8051       // BuildBinOp already emitted error, this one is to point user to upper
8052       // and lower bound, and to tell what is passed to 'operator-'.
8053       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8054           << Upper->getSourceRange() << Lower->getSourceRange();
8055       return nullptr;
8056     }
8057 
8058     if (!Diff.isUsable())
8059       return nullptr;
8060 
8061     // Upper - Lower [- 1]
8062     if (TestIsStrictOp)
8063       Diff = SemaRef.BuildBinOp(
8064           S, DefaultLoc, BO_Sub, Diff.get(),
8065           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8066     if (!Diff.isUsable())
8067       return nullptr;
8068 
8069     if (RoundToStep) {
8070       // Upper - Lower [- 1] + Step
8071       Diff =
8072           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8073       if (!Diff.isUsable())
8074         return nullptr;
8075     }
8076   }
8077 
8078   // Parentheses (for dumping/debugging purposes only).
8079   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8080   if (!Diff.isUsable())
8081     return nullptr;
8082 
8083   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8084   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8085   if (!Diff.isUsable())
8086     return nullptr;
8087 
8088   return Diff.get();
8089 }
8090 
8091 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8092 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8093     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8094     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8095   QualType VarType = LCDecl->getType().getNonReferenceType();
8096   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8097       !SemaRef.getLangOpts().CPlusPlus)
8098     return nullptr;
8099   Expr *LBVal = LB;
8100   Expr *UBVal = UB;
8101   // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8102   // max(LB(MinVal), LB(MaxVal))
8103   if (InitDependOnLC) {
8104     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8105     if (!IS.MinValue || !IS.MaxValue)
8106       return nullptr;
8107     // OuterVar = Min
8108     ExprResult MinValue =
8109         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8110     if (!MinValue.isUsable())
8111       return nullptr;
8112 
8113     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8114                                              IS.CounterVar, MinValue.get());
8115     if (!LBMinVal.isUsable())
8116       return nullptr;
8117     // OuterVar = Min, LBVal
8118     LBMinVal =
8119         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8120     if (!LBMinVal.isUsable())
8121       return nullptr;
8122     // (OuterVar = Min, LBVal)
8123     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8124     if (!LBMinVal.isUsable())
8125       return nullptr;
8126 
8127     // OuterVar = Max
8128     ExprResult MaxValue =
8129         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8130     if (!MaxValue.isUsable())
8131       return nullptr;
8132 
8133     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8134                                              IS.CounterVar, MaxValue.get());
8135     if (!LBMaxVal.isUsable())
8136       return nullptr;
8137     // OuterVar = Max, LBVal
8138     LBMaxVal =
8139         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8140     if (!LBMaxVal.isUsable())
8141       return nullptr;
8142     // (OuterVar = Max, LBVal)
8143     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8144     if (!LBMaxVal.isUsable())
8145       return nullptr;
8146 
8147     Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8148     Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8149     if (!LBMin || !LBMax)
8150       return nullptr;
8151     // LB(MinVal) < LB(MaxVal)
8152     ExprResult MinLessMaxRes =
8153         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8154     if (!MinLessMaxRes.isUsable())
8155       return nullptr;
8156     Expr *MinLessMax =
8157         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8158     if (!MinLessMax)
8159       return nullptr;
8160     if (TestIsLessOp.getValue()) {
8161       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8162       // LB(MaxVal))
8163       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8164                                                     MinLessMax, LBMin, LBMax);
8165       if (!MinLB.isUsable())
8166         return nullptr;
8167       LBVal = MinLB.get();
8168     } else {
8169       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8170       // LB(MaxVal))
8171       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8172                                                     MinLessMax, LBMax, LBMin);
8173       if (!MaxLB.isUsable())
8174         return nullptr;
8175       LBVal = MaxLB.get();
8176     }
8177   }
8178   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8179   // min(UB(MinVal), UB(MaxVal))
8180   if (CondDependOnLC) {
8181     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8182     if (!IS.MinValue || !IS.MaxValue)
8183       return nullptr;
8184     // OuterVar = Min
8185     ExprResult MinValue =
8186         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8187     if (!MinValue.isUsable())
8188       return nullptr;
8189 
8190     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8191                                              IS.CounterVar, MinValue.get());
8192     if (!UBMinVal.isUsable())
8193       return nullptr;
8194     // OuterVar = Min, UBVal
8195     UBMinVal =
8196         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8197     if (!UBMinVal.isUsable())
8198       return nullptr;
8199     // (OuterVar = Min, UBVal)
8200     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8201     if (!UBMinVal.isUsable())
8202       return nullptr;
8203 
8204     // OuterVar = Max
8205     ExprResult MaxValue =
8206         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8207     if (!MaxValue.isUsable())
8208       return nullptr;
8209 
8210     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8211                                              IS.CounterVar, MaxValue.get());
8212     if (!UBMaxVal.isUsable())
8213       return nullptr;
8214     // OuterVar = Max, UBVal
8215     UBMaxVal =
8216         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8217     if (!UBMaxVal.isUsable())
8218       return nullptr;
8219     // (OuterVar = Max, UBVal)
8220     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8221     if (!UBMaxVal.isUsable())
8222       return nullptr;
8223 
8224     Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8225     Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8226     if (!UBMin || !UBMax)
8227       return nullptr;
8228     // UB(MinVal) > UB(MaxVal)
8229     ExprResult MinGreaterMaxRes =
8230         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8231     if (!MinGreaterMaxRes.isUsable())
8232       return nullptr;
8233     Expr *MinGreaterMax =
8234         tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8235     if (!MinGreaterMax)
8236       return nullptr;
8237     if (TestIsLessOp.getValue()) {
8238       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8239       // UB(MaxVal))
8240       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8241           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8242       if (!MaxUB.isUsable())
8243         return nullptr;
8244       UBVal = MaxUB.get();
8245     } else {
8246       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8247       // UB(MaxVal))
8248       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8249           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8250       if (!MinUB.isUsable())
8251         return nullptr;
8252       UBVal = MinUB.get();
8253     }
8254   }
8255   Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8256   Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8257   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8258   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8259   if (!Upper || !Lower)
8260     return nullptr;
8261 
8262   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8263                                       Step, VarType, TestIsStrictOp,
8264                                       /*RoundToStep=*/true, Captures);
8265   if (!Diff.isUsable())
8266     return nullptr;
8267 
8268   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8269   QualType Type = Diff.get()->getType();
8270   ASTContext &C = SemaRef.Context;
8271   bool UseVarType = VarType->hasIntegerRepresentation() &&
8272                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8273   if (!Type->isIntegerType() || UseVarType) {
8274     unsigned NewSize =
8275         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8276     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8277                                : Type->hasSignedIntegerRepresentation();
8278     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8279     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8280       Diff = SemaRef.PerformImplicitConversion(
8281           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8282       if (!Diff.isUsable())
8283         return nullptr;
8284     }
8285   }
8286   if (LimitedType) {
8287     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8288     if (NewSize != C.getTypeSize(Type)) {
8289       if (NewSize < C.getTypeSize(Type)) {
8290         assert(NewSize == 64 && "incorrect loop var size");
8291         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8292             << InitSrcRange << ConditionSrcRange;
8293       }
8294       QualType NewType = C.getIntTypeForBitwidth(
8295           NewSize, Type->hasSignedIntegerRepresentation() ||
8296                        C.getTypeSize(Type) < NewSize);
8297       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8298         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8299                                                  Sema::AA_Converting, true);
8300         if (!Diff.isUsable())
8301           return nullptr;
8302       }
8303     }
8304   }
8305 
8306   return Diff.get();
8307 }
8308 
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8309 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8310     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8311   // Do not build for iterators, they cannot be used in non-rectangular loop
8312   // nests.
8313   if (LCDecl->getType()->isRecordType())
8314     return std::make_pair(nullptr, nullptr);
8315   // If we subtract, the min is in the condition, otherwise the min is in the
8316   // init value.
8317   Expr *MinExpr = nullptr;
8318   Expr *MaxExpr = nullptr;
8319   Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8320   Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8321   bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8322                                            : CondDependOnLC.hasValue();
8323   bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8324                                            : InitDependOnLC.hasValue();
8325   Expr *Lower =
8326       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8327   Expr *Upper =
8328       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8329   if (!Upper || !Lower)
8330     return std::make_pair(nullptr, nullptr);
8331 
8332   if (TestIsLessOp.getValue())
8333     MinExpr = Lower;
8334   else
8335     MaxExpr = Upper;
8336 
8337   // Build minimum/maximum value based on number of iterations.
8338   QualType VarType = LCDecl->getType().getNonReferenceType();
8339 
8340   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8341                                       Step, VarType, TestIsStrictOp,
8342                                       /*RoundToStep=*/false, Captures);
8343   if (!Diff.isUsable())
8344     return std::make_pair(nullptr, nullptr);
8345 
8346   // ((Upper - Lower [- 1]) / Step) * Step
8347   // Parentheses (for dumping/debugging purposes only).
8348   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8349   if (!Diff.isUsable())
8350     return std::make_pair(nullptr, nullptr);
8351 
8352   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8353   if (!NewStep.isUsable())
8354     return std::make_pair(nullptr, nullptr);
8355   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8356   if (!Diff.isUsable())
8357     return std::make_pair(nullptr, nullptr);
8358 
8359   // Parentheses (for dumping/debugging purposes only).
8360   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8361   if (!Diff.isUsable())
8362     return std::make_pair(nullptr, nullptr);
8363 
8364   // Convert to the ptrdiff_t, if original type is pointer.
8365   if (VarType->isAnyPointerType() &&
8366       !SemaRef.Context.hasSameType(
8367           Diff.get()->getType(),
8368           SemaRef.Context.getUnsignedPointerDiffType())) {
8369     Diff = SemaRef.PerformImplicitConversion(
8370         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8371         Sema::AA_Converting, /*AllowExplicit=*/true);
8372   }
8373   if (!Diff.isUsable())
8374     return std::make_pair(nullptr, nullptr);
8375 
8376   if (TestIsLessOp.getValue()) {
8377     // MinExpr = Lower;
8378     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8379     Diff = SemaRef.BuildBinOp(
8380         S, DefaultLoc, BO_Add,
8381         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8382         Diff.get());
8383     if (!Diff.isUsable())
8384       return std::make_pair(nullptr, nullptr);
8385   } else {
8386     // MaxExpr = Upper;
8387     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8388     Diff = SemaRef.BuildBinOp(
8389         S, DefaultLoc, BO_Sub,
8390         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8391         Diff.get());
8392     if (!Diff.isUsable())
8393       return std::make_pair(nullptr, nullptr);
8394   }
8395 
8396   // Convert to the original type.
8397   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8398     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8399                                              Sema::AA_Converting,
8400                                              /*AllowExplicit=*/true);
8401   if (!Diff.isUsable())
8402     return std::make_pair(nullptr, nullptr);
8403 
8404   Sema::TentativeAnalysisScope Trap(SemaRef);
8405   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8406   if (!Diff.isUsable())
8407     return std::make_pair(nullptr, nullptr);
8408 
8409   if (TestIsLessOp.getValue())
8410     MaxExpr = Diff.get();
8411   else
8412     MinExpr = Diff.get();
8413 
8414   return std::make_pair(MinExpr, MaxExpr);
8415 }
8416 
buildFinalCondition(Scope * S) const8417 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8418   if (InitDependOnLC || CondDependOnLC)
8419     return Condition;
8420   return nullptr;
8421 }
8422 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8423 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8424     Scope *S, Expr *Cond,
8425     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8426   // Do not build a precondition when the condition/initialization is dependent
8427   // to prevent pessimistic early loop exit.
8428   // TODO: this can be improved by calculating min/max values but not sure that
8429   // it will be very effective.
8430   if (CondDependOnLC || InitDependOnLC)
8431     return SemaRef.PerformImplicitConversion(
8432         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8433         SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8434         /*AllowExplicit=*/true).get();
8435 
8436   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8437   Sema::TentativeAnalysisScope Trap(SemaRef);
8438 
8439   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8440   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8441   if (!NewLB.isUsable() || !NewUB.isUsable())
8442     return nullptr;
8443 
8444   ExprResult CondExpr =
8445       SemaRef.BuildBinOp(S, DefaultLoc,
8446                          TestIsLessOp.getValue() ?
8447                            (TestIsStrictOp ? BO_LT : BO_LE) :
8448                            (TestIsStrictOp ? BO_GT : BO_GE),
8449                          NewLB.get(), NewUB.get());
8450   if (CondExpr.isUsable()) {
8451     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8452                                                 SemaRef.Context.BoolTy))
8453       CondExpr = SemaRef.PerformImplicitConversion(
8454           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8455           /*AllowExplicit=*/true);
8456   }
8457 
8458   // Otherwise use original loop condition and evaluate it in runtime.
8459   return CondExpr.isUsable() ? CondExpr.get() : Cond;
8460 }
8461 
8462 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const8463 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8464     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8465     DSAStackTy &DSA) const {
8466   auto *VD = dyn_cast<VarDecl>(LCDecl);
8467   if (!VD) {
8468     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8469     DeclRefExpr *Ref = buildDeclRefExpr(
8470         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8471     const DSAStackTy::DSAVarData Data =
8472         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8473     // If the loop control decl is explicitly marked as private, do not mark it
8474     // as captured again.
8475     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8476       Captures.insert(std::make_pair(LCRef, Ref));
8477     return Ref;
8478   }
8479   return cast<DeclRefExpr>(LCRef);
8480 }
8481 
buildPrivateCounterVar() const8482 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8483   if (LCDecl && !LCDecl->isInvalidDecl()) {
8484     QualType Type = LCDecl->getType().getNonReferenceType();
8485     VarDecl *PrivateVar = buildVarDecl(
8486         SemaRef, DefaultLoc, Type, LCDecl->getName(),
8487         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8488         isa<VarDecl>(LCDecl)
8489             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8490             : nullptr);
8491     if (PrivateVar->isInvalidDecl())
8492       return nullptr;
8493     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8494   }
8495   return nullptr;
8496 }
8497 
8498 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const8499 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8500 
8501 /// Build step of the counter be used for codegen.
buildCounterStep() const8502 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8503 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)8504 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8505     Scope *S, Expr *Counter,
8506     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8507     Expr *Inc, OverloadedOperatorKind OOK) {
8508   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8509   if (!Cnt)
8510     return nullptr;
8511   if (Inc) {
8512     assert((OOK == OO_Plus || OOK == OO_Minus) &&
8513            "Expected only + or - operations for depend clauses.");
8514     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8515     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8516     if (!Cnt)
8517       return nullptr;
8518   }
8519   QualType VarType = LCDecl->getType().getNonReferenceType();
8520   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8521       !SemaRef.getLangOpts().CPlusPlus)
8522     return nullptr;
8523   // Upper - Lower
8524   Expr *Upper = TestIsLessOp.getValue()
8525                     ? Cnt
8526                     : tryBuildCapture(SemaRef, LB, Captures).get();
8527   Expr *Lower = TestIsLessOp.getValue()
8528                     ? tryBuildCapture(SemaRef, LB, Captures).get()
8529                     : Cnt;
8530   if (!Upper || !Lower)
8531     return nullptr;
8532 
8533   ExprResult Diff = calculateNumIters(
8534       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8535       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8536   if (!Diff.isUsable())
8537     return nullptr;
8538 
8539   return Diff.get();
8540 }
8541 } // namespace
8542 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)8543 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8544   assert(getLangOpts().OpenMP && "OpenMP is not active.");
8545   assert(Init && "Expected loop in canonical form.");
8546   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
8547   if (AssociatedLoops > 0 &&
8548       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
8549     DSAStack->loopStart();
8550     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8551                                     *DSAStack, ForLoc);
8552     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8553       if (ValueDecl *D = ISC.getLoopDecl()) {
8554         auto *VD = dyn_cast<VarDecl>(D);
8555         DeclRefExpr *PrivateRef = nullptr;
8556         if (!VD) {
8557           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8558             VD = Private;
8559           } else {
8560             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8561                                       /*WithInit=*/false);
8562             VD = cast<VarDecl>(PrivateRef->getDecl());
8563           }
8564         }
8565         DSAStack->addLoopControlVariable(D, VD);
8566         const Decl *LD = DSAStack->getPossiblyLoopCunter();
8567         if (LD != D->getCanonicalDecl()) {
8568           DSAStack->resetPossibleLoopCounter();
8569           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8570             MarkDeclarationsReferencedInExpr(
8571                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8572                                  Var->getType().getNonLValueExprType(Context),
8573                                  ForLoc, /*RefersToCapture=*/true));
8574         }
8575         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8576         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8577         // Referenced in a Construct, C/C++]. The loop iteration variable in the
8578         // associated for-loop of a simd construct with just one associated
8579         // for-loop may be listed in a linear clause with a constant-linear-step
8580         // that is the increment of the associated for-loop. The loop iteration
8581         // variable(s) in the associated for-loop(s) of a for or parallel for
8582         // construct may be listed in a private or lastprivate clause.
8583         DSAStackTy::DSAVarData DVar =
8584             DSAStack->getTopDSA(D, /*FromParent=*/false);
8585         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8586         // is declared in the loop and it is predetermined as a private.
8587         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8588         OpenMPClauseKind PredeterminedCKind =
8589             isOpenMPSimdDirective(DKind)
8590                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8591                 : OMPC_private;
8592         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8593               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8594               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8595                                          DVar.CKind != OMPC_private))) ||
8596              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8597                DKind == OMPD_master_taskloop ||
8598                DKind == OMPD_parallel_master_taskloop ||
8599                isOpenMPDistributeDirective(DKind)) &&
8600               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8601               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8602             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8603           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8604               << getOpenMPClauseName(DVar.CKind)
8605               << getOpenMPDirectiveName(DKind)
8606               << getOpenMPClauseName(PredeterminedCKind);
8607           if (DVar.RefExpr == nullptr)
8608             DVar.CKind = PredeterminedCKind;
8609           reportOriginalDsa(*this, DSAStack, D, DVar,
8610                             /*IsLoopIterVar=*/true);
8611         } else if (LoopDeclRefExpr) {
8612           // Make the loop iteration variable private (for worksharing
8613           // constructs), linear (for simd directives with the only one
8614           // associated loop) or lastprivate (for simd directives with several
8615           // collapsed or ordered loops).
8616           if (DVar.CKind == OMPC_unknown)
8617             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8618                              PrivateRef);
8619         }
8620       }
8621     }
8622     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
8623   }
8624 }
8625 
8626 /// Called on a for stmt to check and extract its iteration space
8627 /// 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)8628 static bool checkOpenMPIterationSpace(
8629     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8630     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8631     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8632     Expr *OrderedLoopCountExpr,
8633     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8634     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8635     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8636   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8637   // OpenMP [2.9.1, Canonical Loop Form]
8638   //   for (init-expr; test-expr; incr-expr) structured-block
8639   //   for (range-decl: range-expr) structured-block
8640   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8641     S = CanonLoop->getLoopStmt();
8642   auto *For = dyn_cast_or_null<ForStmt>(S);
8643   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8644   // Ranged for is supported only in OpenMP 5.0.
8645   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8646     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8647         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8648         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8649         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8650     if (TotalNestedLoopCount > 1) {
8651       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8652         SemaRef.Diag(DSA.getConstructLoc(),
8653                      diag::note_omp_collapse_ordered_expr)
8654             << 2 << CollapseLoopCountExpr->getSourceRange()
8655             << OrderedLoopCountExpr->getSourceRange();
8656       else if (CollapseLoopCountExpr)
8657         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8658                      diag::note_omp_collapse_ordered_expr)
8659             << 0 << CollapseLoopCountExpr->getSourceRange();
8660       else
8661         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8662                      diag::note_omp_collapse_ordered_expr)
8663             << 1 << OrderedLoopCountExpr->getSourceRange();
8664     }
8665     return true;
8666   }
8667   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
8668          "No loop body.");
8669 
8670   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8671                                   For ? For->getForLoc() : CXXFor->getForLoc());
8672 
8673   // Check init.
8674   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8675   if (ISC.checkAndSetInit(Init))
8676     return true;
8677 
8678   bool HasErrors = false;
8679 
8680   // Check loop variable's type.
8681   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8682     // OpenMP [2.6, Canonical Loop Form]
8683     // Var is one of the following:
8684     //   A variable of signed or unsigned integer type.
8685     //   For C++, a variable of a random access iterator type.
8686     //   For C, a variable of a pointer type.
8687     QualType VarType = LCDecl->getType().getNonReferenceType();
8688     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8689         !VarType->isPointerType() &&
8690         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8691       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8692           << SemaRef.getLangOpts().CPlusPlus;
8693       HasErrors = true;
8694     }
8695 
8696     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8697     // a Construct
8698     // The loop iteration variable(s) in the associated for-loop(s) of a for or
8699     // parallel for construct is (are) private.
8700     // The loop iteration variable in the associated for-loop of a simd
8701     // construct with just one associated for-loop is linear with a
8702     // constant-linear-step that is the increment of the associated for-loop.
8703     // Exclude loop var from the list of variables with implicitly defined data
8704     // sharing attributes.
8705     VarsWithImplicitDSA.erase(LCDecl);
8706 
8707     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8708 
8709     // Check test-expr.
8710     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8711 
8712     // Check incr-expr.
8713     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8714   }
8715 
8716   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8717     return HasErrors;
8718 
8719   // Build the loop's iteration space representation.
8720   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8721       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8722   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8723       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8724                              (isOpenMPWorksharingDirective(DKind) ||
8725                               isOpenMPTaskLoopDirective(DKind) ||
8726                               isOpenMPDistributeDirective(DKind) ||
8727                               isOpenMPLoopTransformationDirective(DKind)),
8728                              Captures);
8729   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8730       ISC.buildCounterVar(Captures, DSA);
8731   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8732       ISC.buildPrivateCounterVar();
8733   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8734   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8735   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8736   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8737       ISC.getConditionSrcRange();
8738   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8739       ISC.getIncrementSrcRange();
8740   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8741   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8742       ISC.isStrictTestOp();
8743   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8744            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8745       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8746   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8747       ISC.buildFinalCondition(DSA.getCurScope());
8748   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8749       ISC.doesInitDependOnLC();
8750   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8751       ISC.doesCondDependOnLC();
8752   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8753       ISC.getLoopDependentIdx();
8754 
8755   HasErrors |=
8756       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8757        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8758        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8759        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8760        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8761        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8762   if (!HasErrors && DSA.isOrderedRegion()) {
8763     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8764       if (CurrentNestedLoopCount <
8765           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8766         DSA.getOrderedRegionParam().second->setLoopNumIterations(
8767             CurrentNestedLoopCount,
8768             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8769         DSA.getOrderedRegionParam().second->setLoopCounter(
8770             CurrentNestedLoopCount,
8771             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8772       }
8773     }
8774     for (auto &Pair : DSA.getDoacrossDependClauses()) {
8775       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8776         // Erroneous case - clause has some problems.
8777         continue;
8778       }
8779       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8780           Pair.second.size() <= CurrentNestedLoopCount) {
8781         // Erroneous case - clause has some problems.
8782         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8783         continue;
8784       }
8785       Expr *CntValue;
8786       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8787         CntValue = ISC.buildOrderedLoopData(
8788             DSA.getCurScope(),
8789             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8790             Pair.first->getDependencyLoc());
8791       else
8792         CntValue = ISC.buildOrderedLoopData(
8793             DSA.getCurScope(),
8794             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8795             Pair.first->getDependencyLoc(),
8796             Pair.second[CurrentNestedLoopCount].first,
8797             Pair.second[CurrentNestedLoopCount].second);
8798       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8799     }
8800   }
8801 
8802   return HasErrors;
8803 }
8804 
8805 /// Build 'VarRef = Start.
8806 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8807 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8808                  ExprResult Start, bool IsNonRectangularLB,
8809                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8810   // Build 'VarRef = Start.
8811   ExprResult NewStart = IsNonRectangularLB
8812                             ? Start.get()
8813                             : tryBuildCapture(SemaRef, Start.get(), Captures);
8814   if (!NewStart.isUsable())
8815     return ExprError();
8816   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8817                                    VarRef.get()->getType())) {
8818     NewStart = SemaRef.PerformImplicitConversion(
8819         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8820         /*AllowExplicit=*/true);
8821     if (!NewStart.isUsable())
8822       return ExprError();
8823   }
8824 
8825   ExprResult Init =
8826       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8827   return Init;
8828 }
8829 
8830 /// 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)8831 static ExprResult buildCounterUpdate(
8832     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8833     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8834     bool IsNonRectangularLB,
8835     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8836   // Add parentheses (for debugging purposes only).
8837   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8838   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8839       !Step.isUsable())
8840     return ExprError();
8841 
8842   ExprResult NewStep = Step;
8843   if (Captures)
8844     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8845   if (NewStep.isInvalid())
8846     return ExprError();
8847   ExprResult Update =
8848       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8849   if (!Update.isUsable())
8850     return ExprError();
8851 
8852   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8853   // 'VarRef = Start (+|-) Iter * Step'.
8854   if (!Start.isUsable())
8855     return ExprError();
8856   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8857   if (!NewStart.isUsable())
8858     return ExprError();
8859   if (Captures && !IsNonRectangularLB)
8860     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8861   if (NewStart.isInvalid())
8862     return ExprError();
8863 
8864   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8865   ExprResult SavedUpdate = Update;
8866   ExprResult UpdateVal;
8867   if (VarRef.get()->getType()->isOverloadableType() ||
8868       NewStart.get()->getType()->isOverloadableType() ||
8869       Update.get()->getType()->isOverloadableType()) {
8870     Sema::TentativeAnalysisScope Trap(SemaRef);
8871 
8872     Update =
8873         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8874     if (Update.isUsable()) {
8875       UpdateVal =
8876           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8877                              VarRef.get(), SavedUpdate.get());
8878       if (UpdateVal.isUsable()) {
8879         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8880                                             UpdateVal.get());
8881       }
8882     }
8883   }
8884 
8885   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8886   if (!Update.isUsable() || !UpdateVal.isUsable()) {
8887     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8888                                 NewStart.get(), SavedUpdate.get());
8889     if (!Update.isUsable())
8890       return ExprError();
8891 
8892     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8893                                      VarRef.get()->getType())) {
8894       Update = SemaRef.PerformImplicitConversion(
8895           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8896       if (!Update.isUsable())
8897         return ExprError();
8898     }
8899 
8900     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8901   }
8902   return Update;
8903 }
8904 
8905 /// Convert integer expression \a E to make it have at least \a Bits
8906 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8907 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8908   if (E == nullptr)
8909     return ExprError();
8910   ASTContext &C = SemaRef.Context;
8911   QualType OldType = E->getType();
8912   unsigned HasBits = C.getTypeSize(OldType);
8913   if (HasBits >= Bits)
8914     return ExprResult(E);
8915   // OK to convert to signed, because new type has more bits than old.
8916   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8917   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8918                                            true);
8919 }
8920 
8921 /// Check if the given expression \a E is a constant integer that fits
8922 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8923 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8924   if (E == nullptr)
8925     return false;
8926   if (Optional<llvm::APSInt> Result =
8927           E->getIntegerConstantExpr(SemaRef.Context))
8928     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8929   return false;
8930 }
8931 
8932 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8933 static Stmt *buildPreInits(ASTContext &Context,
8934                            MutableArrayRef<Decl *> PreInits) {
8935   if (!PreInits.empty()) {
8936     return new (Context) DeclStmt(
8937         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8938         SourceLocation(), SourceLocation());
8939   }
8940   return nullptr;
8941 }
8942 
8943 /// Build preinits statement for the given declarations.
8944 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8945 buildPreInits(ASTContext &Context,
8946               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8947   if (!Captures.empty()) {
8948     SmallVector<Decl *, 16> PreInits;
8949     for (const auto &Pair : Captures)
8950       PreInits.push_back(Pair.second->getDecl());
8951     return buildPreInits(Context, PreInits);
8952   }
8953   return nullptr;
8954 }
8955 
8956 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8957 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8958   Expr *PostUpdate = nullptr;
8959   if (!PostUpdates.empty()) {
8960     for (Expr *E : PostUpdates) {
8961       Expr *ConvE = S.BuildCStyleCastExpr(
8962                          E->getExprLoc(),
8963                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8964                          E->getExprLoc(), E)
8965                         .get();
8966       PostUpdate = PostUpdate
8967                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8968                                               PostUpdate, ConvE)
8969                              .get()
8970                        : ConvE;
8971     }
8972   }
8973   return PostUpdate;
8974 }
8975 
8976 /// Called on a for stmt to check itself and nested loops (if any).
8977 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8978 /// number of collapsed loops otherwise.
8979 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopBasedDirective::HelperExprs & Built)8980 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8981                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8982                 DSAStackTy &DSA,
8983                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8984                 OMPLoopBasedDirective::HelperExprs &Built) {
8985   unsigned NestedLoopCount = 1;
8986   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8987                                     !isOpenMPLoopTransformationDirective(DKind);
8988 
8989   if (CollapseLoopCountExpr) {
8990     // Found 'collapse' clause - calculate collapse number.
8991     Expr::EvalResult Result;
8992     if (!CollapseLoopCountExpr->isValueDependent() &&
8993         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8994       NestedLoopCount = Result.Val.getInt().getLimitedValue();
8995     } else {
8996       Built.clear(/*Size=*/1);
8997       return 1;
8998     }
8999   }
9000   unsigned OrderedLoopCount = 1;
9001   if (OrderedLoopCountExpr) {
9002     // Found 'ordered' clause - calculate collapse number.
9003     Expr::EvalResult EVResult;
9004     if (!OrderedLoopCountExpr->isValueDependent() &&
9005         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9006                                             SemaRef.getASTContext())) {
9007       llvm::APSInt Result = EVResult.Val.getInt();
9008       if (Result.getLimitedValue() < NestedLoopCount) {
9009         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9010                      diag::err_omp_wrong_ordered_loop_count)
9011             << OrderedLoopCountExpr->getSourceRange();
9012         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9013                      diag::note_collapse_loop_count)
9014             << CollapseLoopCountExpr->getSourceRange();
9015       }
9016       OrderedLoopCount = Result.getLimitedValue();
9017     } else {
9018       Built.clear(/*Size=*/1);
9019       return 1;
9020     }
9021   }
9022   // This is helper routine for loop directives (e.g., 'for', 'simd',
9023   // 'for simd', etc.).
9024   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9025   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9026   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9027   if (!OMPLoopBasedDirective::doForAllLoops(
9028           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9029           SupportsNonPerfectlyNested, NumLoops,
9030           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9031            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9032            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9033             if (checkOpenMPIterationSpace(
9034                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9035                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9036                     VarsWithImplicitDSA, IterSpaces, Captures))
9037               return true;
9038             if (Cnt > 0 && Cnt >= NestedLoopCount &&
9039                 IterSpaces[Cnt].CounterVar) {
9040               // Handle initialization of captured loop iterator variables.
9041               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9042               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9043                 Captures[DRE] = DRE;
9044               }
9045             }
9046             return false;
9047           },
9048           [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9049             Stmt *DependentPreInits = Transform->getPreInits();
9050             if (!DependentPreInits)
9051               return;
9052             for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9053               auto *D = cast<VarDecl>(C);
9054               DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9055                                                   Transform->getBeginLoc());
9056               Captures[Ref] = Ref;
9057             }
9058           }))
9059     return 0;
9060 
9061   Built.clear(/* size */ NestedLoopCount);
9062 
9063   if (SemaRef.CurContext->isDependentContext())
9064     return NestedLoopCount;
9065 
9066   // An example of what is generated for the following code:
9067   //
9068   //   #pragma omp simd collapse(2) ordered(2)
9069   //   for (i = 0; i < NI; ++i)
9070   //     for (k = 0; k < NK; ++k)
9071   //       for (j = J0; j < NJ; j+=2) {
9072   //         <loop body>
9073   //       }
9074   //
9075   // We generate the code below.
9076   // Note: the loop body may be outlined in CodeGen.
9077   // Note: some counters may be C++ classes, operator- is used to find number of
9078   // iterations and operator+= to calculate counter value.
9079   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9080   // or i64 is currently supported).
9081   //
9082   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9083   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9084   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9085   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9086   //     // similar updates for vars in clauses (e.g. 'linear')
9087   //     <loop body (using local i and j)>
9088   //   }
9089   //   i = NI; // assign final values of counters
9090   //   j = NJ;
9091   //
9092 
9093   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9094   // the iteration counts of the collapsed for loops.
9095   // Precondition tests if there is at least one iteration (all conditions are
9096   // true).
9097   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9098   Expr *N0 = IterSpaces[0].NumIterations;
9099   ExprResult LastIteration32 =
9100       widenIterationCount(/*Bits=*/32,
9101                           SemaRef
9102                               .PerformImplicitConversion(
9103                                   N0->IgnoreImpCasts(), N0->getType(),
9104                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9105                               .get(),
9106                           SemaRef);
9107   ExprResult LastIteration64 = widenIterationCount(
9108       /*Bits=*/64,
9109       SemaRef
9110           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9111                                      Sema::AA_Converting,
9112                                      /*AllowExplicit=*/true)
9113           .get(),
9114       SemaRef);
9115 
9116   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9117     return NestedLoopCount;
9118 
9119   ASTContext &C = SemaRef.Context;
9120   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9121 
9122   Scope *CurScope = DSA.getCurScope();
9123   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9124     if (PreCond.isUsable()) {
9125       PreCond =
9126           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9127                              PreCond.get(), IterSpaces[Cnt].PreCond);
9128     }
9129     Expr *N = IterSpaces[Cnt].NumIterations;
9130     SourceLocation Loc = N->getExprLoc();
9131     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9132     if (LastIteration32.isUsable())
9133       LastIteration32 = SemaRef.BuildBinOp(
9134           CurScope, Loc, BO_Mul, LastIteration32.get(),
9135           SemaRef
9136               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9137                                          Sema::AA_Converting,
9138                                          /*AllowExplicit=*/true)
9139               .get());
9140     if (LastIteration64.isUsable())
9141       LastIteration64 = SemaRef.BuildBinOp(
9142           CurScope, Loc, BO_Mul, LastIteration64.get(),
9143           SemaRef
9144               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9145                                          Sema::AA_Converting,
9146                                          /*AllowExplicit=*/true)
9147               .get());
9148   }
9149 
9150   // Choose either the 32-bit or 64-bit version.
9151   ExprResult LastIteration = LastIteration64;
9152   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9153       (LastIteration32.isUsable() &&
9154        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9155        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9156         fitsInto(
9157             /*Bits=*/32,
9158             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9159             LastIteration64.get(), SemaRef))))
9160     LastIteration = LastIteration32;
9161   QualType VType = LastIteration.get()->getType();
9162   QualType RealVType = VType;
9163   QualType StrideVType = VType;
9164   if (isOpenMPTaskLoopDirective(DKind)) {
9165     VType =
9166         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9167     StrideVType =
9168         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9169   }
9170 
9171   if (!LastIteration.isUsable())
9172     return 0;
9173 
9174   // Save the number of iterations.
9175   ExprResult NumIterations = LastIteration;
9176   {
9177     LastIteration = SemaRef.BuildBinOp(
9178         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9179         LastIteration.get(),
9180         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9181     if (!LastIteration.isUsable())
9182       return 0;
9183   }
9184 
9185   // Calculate the last iteration number beforehand instead of doing this on
9186   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9187   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9188   ExprResult CalcLastIteration;
9189   if (!IsConstant) {
9190     ExprResult SaveRef =
9191         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9192     LastIteration = SaveRef;
9193 
9194     // Prepare SaveRef + 1.
9195     NumIterations = SemaRef.BuildBinOp(
9196         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9197         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9198     if (!NumIterations.isUsable())
9199       return 0;
9200   }
9201 
9202   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9203 
9204   // Build variables passed into runtime, necessary for worksharing directives.
9205   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9206   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9207       isOpenMPDistributeDirective(DKind) ||
9208       isOpenMPLoopTransformationDirective(DKind)) {
9209     // Lower bound variable, initialized with zero.
9210     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9211     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9212     SemaRef.AddInitializerToDecl(LBDecl,
9213                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9214                                  /*DirectInit*/ false);
9215 
9216     // Upper bound variable, initialized with last iteration number.
9217     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9218     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9219     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9220                                  /*DirectInit*/ false);
9221 
9222     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9223     // This will be used to implement clause 'lastprivate'.
9224     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9225     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9226     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9227     SemaRef.AddInitializerToDecl(ILDecl,
9228                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9229                                  /*DirectInit*/ false);
9230 
9231     // Stride variable returned by runtime (we initialize it to 1 by default).
9232     VarDecl *STDecl =
9233         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9234     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9235     SemaRef.AddInitializerToDecl(STDecl,
9236                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9237                                  /*DirectInit*/ false);
9238 
9239     // Build expression: UB = min(UB, LastIteration)
9240     // It is necessary for CodeGen of directives with static scheduling.
9241     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9242                                                 UB.get(), LastIteration.get());
9243     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9244         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9245         LastIteration.get(), UB.get());
9246     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9247                              CondOp.get());
9248     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9249 
9250     // If we have a combined directive that combines 'distribute', 'for' or
9251     // 'simd' we need to be able to access the bounds of the schedule of the
9252     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9253     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9254     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9255       // Lower bound variable, initialized with zero.
9256       VarDecl *CombLBDecl =
9257           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9258       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9259       SemaRef.AddInitializerToDecl(
9260           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9261           /*DirectInit*/ false);
9262 
9263       // Upper bound variable, initialized with last iteration number.
9264       VarDecl *CombUBDecl =
9265           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9266       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9267       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9268                                    /*DirectInit*/ false);
9269 
9270       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9271           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9272       ExprResult CombCondOp =
9273           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9274                                      LastIteration.get(), CombUB.get());
9275       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9276                                    CombCondOp.get());
9277       CombEUB =
9278           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9279 
9280       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9281       // We expect to have at least 2 more parameters than the 'parallel'
9282       // directive does - the lower and upper bounds of the previous schedule.
9283       assert(CD->getNumParams() >= 4 &&
9284              "Unexpected number of parameters in loop combined directive");
9285 
9286       // Set the proper type for the bounds given what we learned from the
9287       // enclosed loops.
9288       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9289       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9290 
9291       // Previous lower and upper bounds are obtained from the region
9292       // parameters.
9293       PrevLB =
9294           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9295       PrevUB =
9296           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9297     }
9298   }
9299 
9300   // Build the iteration variable and its initialization before loop.
9301   ExprResult IV;
9302   ExprResult Init, CombInit;
9303   {
9304     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9305     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9306     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9307                  isOpenMPTaskLoopDirective(DKind) ||
9308                  isOpenMPDistributeDirective(DKind) ||
9309                  isOpenMPLoopTransformationDirective(DKind))
9310                     ? LB.get()
9311                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9312     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9313     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9314 
9315     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9316       Expr *CombRHS =
9317           (isOpenMPWorksharingDirective(DKind) ||
9318            isOpenMPTaskLoopDirective(DKind) ||
9319            isOpenMPDistributeDirective(DKind))
9320               ? CombLB.get()
9321               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9322       CombInit =
9323           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9324       CombInit =
9325           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9326     }
9327   }
9328 
9329   bool UseStrictCompare =
9330       RealVType->hasUnsignedIntegerRepresentation() &&
9331       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9332         return LIS.IsStrictCompare;
9333       });
9334   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9335   // unsigned IV)) for worksharing loops.
9336   SourceLocation CondLoc = AStmt->getBeginLoc();
9337   Expr *BoundUB = UB.get();
9338   if (UseStrictCompare) {
9339     BoundUB =
9340         SemaRef
9341             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9342                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9343             .get();
9344     BoundUB =
9345         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9346   }
9347   ExprResult Cond =
9348       (isOpenMPWorksharingDirective(DKind) ||
9349        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9350        isOpenMPLoopTransformationDirective(DKind))
9351           ? SemaRef.BuildBinOp(CurScope, CondLoc,
9352                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9353                                BoundUB)
9354           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9355                                NumIterations.get());
9356   ExprResult CombDistCond;
9357   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9358     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9359                                       NumIterations.get());
9360   }
9361 
9362   ExprResult CombCond;
9363   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9364     Expr *BoundCombUB = CombUB.get();
9365     if (UseStrictCompare) {
9366       BoundCombUB =
9367           SemaRef
9368               .BuildBinOp(
9369                   CurScope, CondLoc, BO_Add, BoundCombUB,
9370                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9371               .get();
9372       BoundCombUB =
9373           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9374               .get();
9375     }
9376     CombCond =
9377         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9378                            IV.get(), BoundCombUB);
9379   }
9380   // Loop increment (IV = IV + 1)
9381   SourceLocation IncLoc = AStmt->getBeginLoc();
9382   ExprResult Inc =
9383       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9384                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9385   if (!Inc.isUsable())
9386     return 0;
9387   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9388   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9389   if (!Inc.isUsable())
9390     return 0;
9391 
9392   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9393   // Used for directives with static scheduling.
9394   // In combined construct, add combined version that use CombLB and CombUB
9395   // base variables for the update
9396   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9397   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9398       isOpenMPDistributeDirective(DKind) ||
9399       isOpenMPLoopTransformationDirective(DKind)) {
9400     // LB + ST
9401     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9402     if (!NextLB.isUsable())
9403       return 0;
9404     // LB = LB + ST
9405     NextLB =
9406         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9407     NextLB =
9408         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9409     if (!NextLB.isUsable())
9410       return 0;
9411     // UB + ST
9412     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9413     if (!NextUB.isUsable())
9414       return 0;
9415     // UB = UB + ST
9416     NextUB =
9417         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9418     NextUB =
9419         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9420     if (!NextUB.isUsable())
9421       return 0;
9422     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9423       CombNextLB =
9424           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9425       if (!NextLB.isUsable())
9426         return 0;
9427       // LB = LB + ST
9428       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9429                                       CombNextLB.get());
9430       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9431                                                /*DiscardedValue*/ false);
9432       if (!CombNextLB.isUsable())
9433         return 0;
9434       // UB + ST
9435       CombNextUB =
9436           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9437       if (!CombNextUB.isUsable())
9438         return 0;
9439       // UB = UB + ST
9440       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9441                                       CombNextUB.get());
9442       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9443                                                /*DiscardedValue*/ false);
9444       if (!CombNextUB.isUsable())
9445         return 0;
9446     }
9447   }
9448 
9449   // Create increment expression for distribute loop when combined in a same
9450   // directive with for as IV = IV + ST; ensure upper bound expression based
9451   // on PrevUB instead of NumIterations - used to implement 'for' when found
9452   // in combination with 'distribute', like in 'distribute parallel for'
9453   SourceLocation DistIncLoc = AStmt->getBeginLoc();
9454   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9455   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9456     DistCond = SemaRef.BuildBinOp(
9457         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9458     assert(DistCond.isUsable() && "distribute cond expr was not built");
9459 
9460     DistInc =
9461         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9462     assert(DistInc.isUsable() && "distribute inc expr was not built");
9463     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9464                                  DistInc.get());
9465     DistInc =
9466         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9467     assert(DistInc.isUsable() && "distribute inc expr was not built");
9468 
9469     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9470     // construct
9471     ExprResult NewPrevUB = PrevUB;
9472     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9473     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9474                                      PrevUB.get()->getType())) {
9475       NewPrevUB = SemaRef.BuildCStyleCastExpr(
9476           DistEUBLoc,
9477           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9478           DistEUBLoc, NewPrevUB.get());
9479       if (!NewPrevUB.isUsable())
9480         return 0;
9481     }
9482     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9483                                                 UB.get(), NewPrevUB.get());
9484     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9485         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9486     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9487                                  CondOp.get());
9488     PrevEUB =
9489         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9490 
9491     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9492     // parallel for is in combination with a distribute directive with
9493     // schedule(static, 1)
9494     Expr *BoundPrevUB = PrevUB.get();
9495     if (UseStrictCompare) {
9496       BoundPrevUB =
9497           SemaRef
9498               .BuildBinOp(
9499                   CurScope, CondLoc, BO_Add, BoundPrevUB,
9500                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9501               .get();
9502       BoundPrevUB =
9503           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9504               .get();
9505     }
9506     ParForInDistCond =
9507         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9508                            IV.get(), BoundPrevUB);
9509   }
9510 
9511   // Build updates and final values of the loop counters.
9512   bool HasErrors = false;
9513   Built.Counters.resize(NestedLoopCount);
9514   Built.Inits.resize(NestedLoopCount);
9515   Built.Updates.resize(NestedLoopCount);
9516   Built.Finals.resize(NestedLoopCount);
9517   Built.DependentCounters.resize(NestedLoopCount);
9518   Built.DependentInits.resize(NestedLoopCount);
9519   Built.FinalsConditions.resize(NestedLoopCount);
9520   {
9521     // We implement the following algorithm for obtaining the
9522     // original loop iteration variable values based on the
9523     // value of the collapsed loop iteration variable IV.
9524     //
9525     // Let n+1 be the number of collapsed loops in the nest.
9526     // Iteration variables (I0, I1, .... In)
9527     // Iteration counts (N0, N1, ... Nn)
9528     //
9529     // Acc = IV;
9530     //
9531     // To compute Ik for loop k, 0 <= k <= n, generate:
9532     //    Prod = N(k+1) * N(k+2) * ... * Nn;
9533     //    Ik = Acc / Prod;
9534     //    Acc -= Ik * Prod;
9535     //
9536     ExprResult Acc = IV;
9537     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9538       LoopIterationSpace &IS = IterSpaces[Cnt];
9539       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9540       ExprResult Iter;
9541 
9542       // Compute prod
9543       ExprResult Prod =
9544           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9545       for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9546         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9547                                   IterSpaces[K].NumIterations);
9548 
9549       // Iter = Acc / Prod
9550       // If there is at least one more inner loop to avoid
9551       // multiplication by 1.
9552       if (Cnt + 1 < NestedLoopCount)
9553         Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9554                                   Acc.get(), Prod.get());
9555       else
9556         Iter = Acc;
9557       if (!Iter.isUsable()) {
9558         HasErrors = true;
9559         break;
9560       }
9561 
9562       // Update Acc:
9563       // Acc -= Iter * Prod
9564       // Check if there is at least one more inner loop to avoid
9565       // multiplication by 1.
9566       if (Cnt + 1 < NestedLoopCount)
9567         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9568                                   Iter.get(), Prod.get());
9569       else
9570         Prod = Iter;
9571       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9572                                Acc.get(), Prod.get());
9573 
9574       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9575       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9576       DeclRefExpr *CounterVar = buildDeclRefExpr(
9577           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9578           /*RefersToCapture=*/true);
9579       ExprResult Init =
9580           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9581                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
9582       if (!Init.isUsable()) {
9583         HasErrors = true;
9584         break;
9585       }
9586       ExprResult Update = buildCounterUpdate(
9587           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9588           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9589       if (!Update.isUsable()) {
9590         HasErrors = true;
9591         break;
9592       }
9593 
9594       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9595       ExprResult Final =
9596           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9597                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
9598                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
9599       if (!Final.isUsable()) {
9600         HasErrors = true;
9601         break;
9602       }
9603 
9604       if (!Update.isUsable() || !Final.isUsable()) {
9605         HasErrors = true;
9606         break;
9607       }
9608       // Save results
9609       Built.Counters[Cnt] = IS.CounterVar;
9610       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9611       Built.Inits[Cnt] = Init.get();
9612       Built.Updates[Cnt] = Update.get();
9613       Built.Finals[Cnt] = Final.get();
9614       Built.DependentCounters[Cnt] = nullptr;
9615       Built.DependentInits[Cnt] = nullptr;
9616       Built.FinalsConditions[Cnt] = nullptr;
9617       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9618         Built.DependentCounters[Cnt] =
9619             Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9620         Built.DependentInits[Cnt] =
9621             Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9622         Built.FinalsConditions[Cnt] = IS.FinalCondition;
9623       }
9624     }
9625   }
9626 
9627   if (HasErrors)
9628     return 0;
9629 
9630   // Save results
9631   Built.IterationVarRef = IV.get();
9632   Built.LastIteration = LastIteration.get();
9633   Built.NumIterations = NumIterations.get();
9634   Built.CalcLastIteration = SemaRef
9635                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
9636                                                      /*DiscardedValue=*/false)
9637                                 .get();
9638   Built.PreCond = PreCond.get();
9639   Built.PreInits = buildPreInits(C, Captures);
9640   Built.Cond = Cond.get();
9641   Built.Init = Init.get();
9642   Built.Inc = Inc.get();
9643   Built.LB = LB.get();
9644   Built.UB = UB.get();
9645   Built.IL = IL.get();
9646   Built.ST = ST.get();
9647   Built.EUB = EUB.get();
9648   Built.NLB = NextLB.get();
9649   Built.NUB = NextUB.get();
9650   Built.PrevLB = PrevLB.get();
9651   Built.PrevUB = PrevUB.get();
9652   Built.DistInc = DistInc.get();
9653   Built.PrevEUB = PrevEUB.get();
9654   Built.DistCombinedFields.LB = CombLB.get();
9655   Built.DistCombinedFields.UB = CombUB.get();
9656   Built.DistCombinedFields.EUB = CombEUB.get();
9657   Built.DistCombinedFields.Init = CombInit.get();
9658   Built.DistCombinedFields.Cond = CombCond.get();
9659   Built.DistCombinedFields.NLB = CombNextLB.get();
9660   Built.DistCombinedFields.NUB = CombNextUB.get();
9661   Built.DistCombinedFields.DistCond = CombDistCond.get();
9662   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9663 
9664   return NestedLoopCount;
9665 }
9666 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)9667 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9668   auto CollapseClauses =
9669       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9670   if (CollapseClauses.begin() != CollapseClauses.end())
9671     return (*CollapseClauses.begin())->getNumForLoops();
9672   return nullptr;
9673 }
9674 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)9675 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9676   auto OrderedClauses =
9677       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9678   if (OrderedClauses.begin() != OrderedClauses.end())
9679     return (*OrderedClauses.begin())->getNumForLoops();
9680   return nullptr;
9681 }
9682 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)9683 static bool checkSimdlenSafelenSpecified(Sema &S,
9684                                          const ArrayRef<OMPClause *> Clauses) {
9685   const OMPSafelenClause *Safelen = nullptr;
9686   const OMPSimdlenClause *Simdlen = nullptr;
9687 
9688   for (const OMPClause *Clause : Clauses) {
9689     if (Clause->getClauseKind() == OMPC_safelen)
9690       Safelen = cast<OMPSafelenClause>(Clause);
9691     else if (Clause->getClauseKind() == OMPC_simdlen)
9692       Simdlen = cast<OMPSimdlenClause>(Clause);
9693     if (Safelen && Simdlen)
9694       break;
9695   }
9696 
9697   if (Simdlen && Safelen) {
9698     const Expr *SimdlenLength = Simdlen->getSimdlen();
9699     const Expr *SafelenLength = Safelen->getSafelen();
9700     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9701         SimdlenLength->isInstantiationDependent() ||
9702         SimdlenLength->containsUnexpandedParameterPack())
9703       return false;
9704     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9705         SafelenLength->isInstantiationDependent() ||
9706         SafelenLength->containsUnexpandedParameterPack())
9707       return false;
9708     Expr::EvalResult SimdlenResult, SafelenResult;
9709     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9710     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9711     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9712     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9713     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9714     // If both simdlen and safelen clauses are specified, the value of the
9715     // simdlen parameter must be less than or equal to the value of the safelen
9716     // parameter.
9717     if (SimdlenRes > SafelenRes) {
9718       S.Diag(SimdlenLength->getExprLoc(),
9719              diag::err_omp_wrong_simdlen_safelen_values)
9720           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9721       return true;
9722     }
9723   }
9724   return false;
9725 }
9726 
9727 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9728 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9729                                SourceLocation StartLoc, SourceLocation EndLoc,
9730                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9731   if (!AStmt)
9732     return StmtError();
9733 
9734   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9735   OMPLoopBasedDirective::HelperExprs B;
9736   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9737   // define the nested loops number.
9738   unsigned NestedLoopCount = checkOpenMPLoop(
9739       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9740       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9741   if (NestedLoopCount == 0)
9742     return StmtError();
9743 
9744   assert((CurContext->isDependentContext() || B.builtAll()) &&
9745          "omp simd loop exprs were not built");
9746 
9747   if (!CurContext->isDependentContext()) {
9748     // Finalize the clauses that need pre-built expressions for CodeGen.
9749     for (OMPClause *C : Clauses) {
9750       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9751         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9752                                      B.NumIterations, *this, CurScope,
9753                                      DSAStack))
9754           return StmtError();
9755     }
9756   }
9757 
9758   if (checkSimdlenSafelenSpecified(*this, Clauses))
9759     return StmtError();
9760 
9761   setFunctionHasBranchProtectedScope();
9762   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9763                                   Clauses, AStmt, B);
9764 }
9765 
9766 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9767 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9768                               SourceLocation StartLoc, SourceLocation EndLoc,
9769                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9770   if (!AStmt)
9771     return StmtError();
9772 
9773   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9774   OMPLoopBasedDirective::HelperExprs B;
9775   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9776   // define the nested loops number.
9777   unsigned NestedLoopCount = checkOpenMPLoop(
9778       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9779       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9780   if (NestedLoopCount == 0)
9781     return StmtError();
9782 
9783   assert((CurContext->isDependentContext() || B.builtAll()) &&
9784          "omp for loop exprs were not built");
9785 
9786   if (!CurContext->isDependentContext()) {
9787     // Finalize the clauses that need pre-built expressions for CodeGen.
9788     for (OMPClause *C : Clauses) {
9789       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9790         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9791                                      B.NumIterations, *this, CurScope,
9792                                      DSAStack))
9793           return StmtError();
9794     }
9795   }
9796 
9797   setFunctionHasBranchProtectedScope();
9798   return OMPForDirective::Create(
9799       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9800       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9801 }
9802 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9803 StmtResult Sema::ActOnOpenMPForSimdDirective(
9804     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9805     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9806   if (!AStmt)
9807     return StmtError();
9808 
9809   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9810   OMPLoopBasedDirective::HelperExprs B;
9811   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9812   // define the nested loops number.
9813   unsigned NestedLoopCount =
9814       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9815                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9816                       VarsWithImplicitDSA, B);
9817   if (NestedLoopCount == 0)
9818     return StmtError();
9819 
9820   assert((CurContext->isDependentContext() || B.builtAll()) &&
9821          "omp for simd loop exprs were not built");
9822 
9823   if (!CurContext->isDependentContext()) {
9824     // Finalize the clauses that need pre-built expressions for CodeGen.
9825     for (OMPClause *C : Clauses) {
9826       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9827         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9828                                      B.NumIterations, *this, CurScope,
9829                                      DSAStack))
9830           return StmtError();
9831     }
9832   }
9833 
9834   if (checkSimdlenSafelenSpecified(*this, Clauses))
9835     return StmtError();
9836 
9837   setFunctionHasBranchProtectedScope();
9838   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9839                                      Clauses, AStmt, B);
9840 }
9841 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9842 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9843                                               Stmt *AStmt,
9844                                               SourceLocation StartLoc,
9845                                               SourceLocation EndLoc) {
9846   if (!AStmt)
9847     return StmtError();
9848 
9849   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9850   auto BaseStmt = AStmt;
9851   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9852     BaseStmt = CS->getCapturedStmt();
9853   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9854     auto S = C->children();
9855     if (S.begin() == S.end())
9856       return StmtError();
9857     // All associated statements must be '#pragma omp section' except for
9858     // the first one.
9859     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9860       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9861         if (SectionStmt)
9862           Diag(SectionStmt->getBeginLoc(),
9863                diag::err_omp_sections_substmt_not_section);
9864         return StmtError();
9865       }
9866       cast<OMPSectionDirective>(SectionStmt)
9867           ->setHasCancel(DSAStack->isCancelRegion());
9868     }
9869   } else {
9870     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9871     return StmtError();
9872   }
9873 
9874   setFunctionHasBranchProtectedScope();
9875 
9876   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9877                                       DSAStack->getTaskgroupReductionRef(),
9878                                       DSAStack->isCancelRegion());
9879 }
9880 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9881 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9882                                              SourceLocation StartLoc,
9883                                              SourceLocation EndLoc) {
9884   if (!AStmt)
9885     return StmtError();
9886 
9887   setFunctionHasBranchProtectedScope();
9888   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9889 
9890   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9891                                      DSAStack->isCancelRegion());
9892 }
9893 
getDirectCallExpr(Expr * E)9894 static Expr *getDirectCallExpr(Expr *E) {
9895   E = E->IgnoreParenCasts()->IgnoreImplicit();
9896   if (auto *CE = dyn_cast<CallExpr>(E))
9897     if (CE->getDirectCallee())
9898       return E;
9899   return nullptr;
9900 }
9901 
ActOnOpenMPDispatchDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9902 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9903                                               Stmt *AStmt,
9904                                               SourceLocation StartLoc,
9905                                               SourceLocation EndLoc) {
9906   if (!AStmt)
9907     return StmtError();
9908 
9909   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9910 
9911   // 5.1 OpenMP
9912   // expression-stmt : an expression statement with one of the following forms:
9913   //   expression = target-call ( [expression-list] );
9914   //   target-call ( [expression-list] );
9915 
9916   SourceLocation TargetCallLoc;
9917 
9918   if (!CurContext->isDependentContext()) {
9919     Expr *TargetCall = nullptr;
9920 
9921     auto *E = dyn_cast<Expr>(S);
9922     if (!E) {
9923       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9924       return StmtError();
9925     }
9926 
9927     E = E->IgnoreParenCasts()->IgnoreImplicit();
9928 
9929     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9930       if (BO->getOpcode() == BO_Assign)
9931         TargetCall = getDirectCallExpr(BO->getRHS());
9932     } else {
9933       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9934         if (COCE->getOperator() == OO_Equal)
9935           TargetCall = getDirectCallExpr(COCE->getArg(1));
9936       if (!TargetCall)
9937         TargetCall = getDirectCallExpr(E);
9938     }
9939     if (!TargetCall) {
9940       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9941       return StmtError();
9942     }
9943     TargetCallLoc = TargetCall->getExprLoc();
9944   }
9945 
9946   setFunctionHasBranchProtectedScope();
9947 
9948   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9949                                       TargetCallLoc);
9950 }
9951 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9952 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9953                                             Stmt *AStmt,
9954                                             SourceLocation StartLoc,
9955                                             SourceLocation EndLoc) {
9956   if (!AStmt)
9957     return StmtError();
9958 
9959   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9960 
9961   setFunctionHasBranchProtectedScope();
9962 
9963   // OpenMP [2.7.3, single Construct, Restrictions]
9964   // The copyprivate clause must not be used with the nowait clause.
9965   const OMPClause *Nowait = nullptr;
9966   const OMPClause *Copyprivate = nullptr;
9967   for (const OMPClause *Clause : Clauses) {
9968     if (Clause->getClauseKind() == OMPC_nowait)
9969       Nowait = Clause;
9970     else if (Clause->getClauseKind() == OMPC_copyprivate)
9971       Copyprivate = Clause;
9972     if (Copyprivate && Nowait) {
9973       Diag(Copyprivate->getBeginLoc(),
9974            diag::err_omp_single_copyprivate_with_nowait);
9975       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9976       return StmtError();
9977     }
9978   }
9979 
9980   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9981 }
9982 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9983 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9984                                             SourceLocation StartLoc,
9985                                             SourceLocation EndLoc) {
9986   if (!AStmt)
9987     return StmtError();
9988 
9989   setFunctionHasBranchProtectedScope();
9990 
9991   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9992 }
9993 
ActOnOpenMPMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9994 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
9995                                             Stmt *AStmt,
9996                                             SourceLocation StartLoc,
9997                                             SourceLocation EndLoc) {
9998   if (!AStmt)
9999     return StmtError();
10000 
10001   setFunctionHasBranchProtectedScope();
10002 
10003   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10004 }
10005 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10006 StmtResult Sema::ActOnOpenMPCriticalDirective(
10007     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10008     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10009   if (!AStmt)
10010     return StmtError();
10011 
10012   bool ErrorFound = false;
10013   llvm::APSInt Hint;
10014   SourceLocation HintLoc;
10015   bool DependentHint = false;
10016   for (const OMPClause *C : Clauses) {
10017     if (C->getClauseKind() == OMPC_hint) {
10018       if (!DirName.getName()) {
10019         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10020         ErrorFound = true;
10021       }
10022       Expr *E = cast<OMPHintClause>(C)->getHint();
10023       if (E->isTypeDependent() || E->isValueDependent() ||
10024           E->isInstantiationDependent()) {
10025         DependentHint = true;
10026       } else {
10027         Hint = E->EvaluateKnownConstInt(Context);
10028         HintLoc = C->getBeginLoc();
10029       }
10030     }
10031   }
10032   if (ErrorFound)
10033     return StmtError();
10034   const auto Pair = DSAStack->getCriticalWithHint(DirName);
10035   if (Pair.first && DirName.getName() && !DependentHint) {
10036     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10037       Diag(StartLoc, diag::err_omp_critical_with_hint);
10038       if (HintLoc.isValid())
10039         Diag(HintLoc, diag::note_omp_critical_hint_here)
10040             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10041       else
10042         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10043       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10044         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10045             << 1
10046             << toString(C->getHint()->EvaluateKnownConstInt(Context),
10047                         /*Radix=*/10, /*Signed=*/false);
10048       } else {
10049         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10050       }
10051     }
10052   }
10053 
10054   setFunctionHasBranchProtectedScope();
10055 
10056   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10057                                            Clauses, AStmt);
10058   if (!Pair.first && DirName.getName() && !DependentHint)
10059     DSAStack->addCriticalWithHint(Dir, Hint);
10060   return Dir;
10061 }
10062 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10063 StmtResult Sema::ActOnOpenMPParallelForDirective(
10064     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10065     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10066   if (!AStmt)
10067     return StmtError();
10068 
10069   auto *CS = cast<CapturedStmt>(AStmt);
10070   // 1.2.2 OpenMP Language Terminology
10071   // Structured block - An executable statement with a single entry at the
10072   // top and a single exit at the bottom.
10073   // The point of exit cannot be a branch out of the structured block.
10074   // longjmp() and throw() must not violate the entry/exit criteria.
10075   CS->getCapturedDecl()->setNothrow();
10076 
10077   OMPLoopBasedDirective::HelperExprs B;
10078   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10079   // define the nested loops number.
10080   unsigned NestedLoopCount =
10081       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10082                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10083                       VarsWithImplicitDSA, B);
10084   if (NestedLoopCount == 0)
10085     return StmtError();
10086 
10087   assert((CurContext->isDependentContext() || B.builtAll()) &&
10088          "omp parallel for loop exprs were not built");
10089 
10090   if (!CurContext->isDependentContext()) {
10091     // Finalize the clauses that need pre-built expressions for CodeGen.
10092     for (OMPClause *C : Clauses) {
10093       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10094         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10095                                      B.NumIterations, *this, CurScope,
10096                                      DSAStack))
10097           return StmtError();
10098     }
10099   }
10100 
10101   setFunctionHasBranchProtectedScope();
10102   return OMPParallelForDirective::Create(
10103       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10104       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10105 }
10106 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10107 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10108     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10109     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10110   if (!AStmt)
10111     return StmtError();
10112 
10113   auto *CS = cast<CapturedStmt>(AStmt);
10114   // 1.2.2 OpenMP Language Terminology
10115   // Structured block - An executable statement with a single entry at the
10116   // top and a single exit at the bottom.
10117   // The point of exit cannot be a branch out of the structured block.
10118   // longjmp() and throw() must not violate the entry/exit criteria.
10119   CS->getCapturedDecl()->setNothrow();
10120 
10121   OMPLoopBasedDirective::HelperExprs B;
10122   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10123   // define the nested loops number.
10124   unsigned NestedLoopCount =
10125       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10126                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10127                       VarsWithImplicitDSA, B);
10128   if (NestedLoopCount == 0)
10129     return StmtError();
10130 
10131   if (!CurContext->isDependentContext()) {
10132     // Finalize the clauses that need pre-built expressions for CodeGen.
10133     for (OMPClause *C : Clauses) {
10134       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10135         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10136                                      B.NumIterations, *this, CurScope,
10137                                      DSAStack))
10138           return StmtError();
10139     }
10140   }
10141 
10142   if (checkSimdlenSafelenSpecified(*this, Clauses))
10143     return StmtError();
10144 
10145   setFunctionHasBranchProtectedScope();
10146   return OMPParallelForSimdDirective::Create(
10147       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10148 }
10149 
10150 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10151 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10152                                          Stmt *AStmt, SourceLocation StartLoc,
10153                                          SourceLocation EndLoc) {
10154   if (!AStmt)
10155     return StmtError();
10156 
10157   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10158   auto *CS = cast<CapturedStmt>(AStmt);
10159   // 1.2.2 OpenMP Language Terminology
10160   // Structured block - An executable statement with a single entry at the
10161   // top and a single exit at the bottom.
10162   // The point of exit cannot be a branch out of the structured block.
10163   // longjmp() and throw() must not violate the entry/exit criteria.
10164   CS->getCapturedDecl()->setNothrow();
10165 
10166   setFunctionHasBranchProtectedScope();
10167 
10168   return OMPParallelMasterDirective::Create(
10169       Context, StartLoc, EndLoc, Clauses, AStmt,
10170       DSAStack->getTaskgroupReductionRef());
10171 }
10172 
10173 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10174 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10175                                            Stmt *AStmt, SourceLocation StartLoc,
10176                                            SourceLocation EndLoc) {
10177   if (!AStmt)
10178     return StmtError();
10179 
10180   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10181   auto BaseStmt = AStmt;
10182   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10183     BaseStmt = CS->getCapturedStmt();
10184   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10185     auto S = C->children();
10186     if (S.begin() == S.end())
10187       return StmtError();
10188     // All associated statements must be '#pragma omp section' except for
10189     // the first one.
10190     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10191       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10192         if (SectionStmt)
10193           Diag(SectionStmt->getBeginLoc(),
10194                diag::err_omp_parallel_sections_substmt_not_section);
10195         return StmtError();
10196       }
10197       cast<OMPSectionDirective>(SectionStmt)
10198           ->setHasCancel(DSAStack->isCancelRegion());
10199     }
10200   } else {
10201     Diag(AStmt->getBeginLoc(),
10202          diag::err_omp_parallel_sections_not_compound_stmt);
10203     return StmtError();
10204   }
10205 
10206   setFunctionHasBranchProtectedScope();
10207 
10208   return OMPParallelSectionsDirective::Create(
10209       Context, StartLoc, EndLoc, Clauses, AStmt,
10210       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10211 }
10212 
10213 /// Find and diagnose mutually exclusive clause kinds.
checkMutuallyExclusiveClauses(Sema & S,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses)10214 static bool checkMutuallyExclusiveClauses(
10215     Sema &S, ArrayRef<OMPClause *> Clauses,
10216     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10217   const OMPClause *PrevClause = nullptr;
10218   bool ErrorFound = false;
10219   for (const OMPClause *C : Clauses) {
10220     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10221       if (!PrevClause) {
10222         PrevClause = C;
10223       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10224         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10225             << getOpenMPClauseName(C->getClauseKind())
10226             << getOpenMPClauseName(PrevClause->getClauseKind());
10227         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10228             << getOpenMPClauseName(PrevClause->getClauseKind());
10229         ErrorFound = true;
10230       }
10231     }
10232   }
10233   return ErrorFound;
10234 }
10235 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10236 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10237                                           Stmt *AStmt, SourceLocation StartLoc,
10238                                           SourceLocation EndLoc) {
10239   if (!AStmt)
10240     return StmtError();
10241 
10242   // OpenMP 5.0, 2.10.1 task Construct
10243   // If a detach clause appears on the directive, then a mergeable clause cannot
10244   // appear on the same directive.
10245   if (checkMutuallyExclusiveClauses(*this, Clauses,
10246                                     {OMPC_detach, OMPC_mergeable}))
10247     return StmtError();
10248 
10249   auto *CS = cast<CapturedStmt>(AStmt);
10250   // 1.2.2 OpenMP Language Terminology
10251   // Structured block - An executable statement with a single entry at the
10252   // top and a single exit at the bottom.
10253   // The point of exit cannot be a branch out of the structured block.
10254   // longjmp() and throw() must not violate the entry/exit criteria.
10255   CS->getCapturedDecl()->setNothrow();
10256 
10257   setFunctionHasBranchProtectedScope();
10258 
10259   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10260                                   DSAStack->isCancelRegion());
10261 }
10262 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)10263 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10264                                                SourceLocation EndLoc) {
10265   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10266 }
10267 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)10268 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10269                                              SourceLocation EndLoc) {
10270   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10271 }
10272 
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)10273 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10274                                               SourceLocation EndLoc) {
10275   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10276 }
10277 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10278 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10279                                                Stmt *AStmt,
10280                                                SourceLocation StartLoc,
10281                                                SourceLocation EndLoc) {
10282   if (!AStmt)
10283     return StmtError();
10284 
10285   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10286 
10287   setFunctionHasBranchProtectedScope();
10288 
10289   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10290                                        AStmt,
10291                                        DSAStack->getTaskgroupReductionRef());
10292 }
10293 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10294 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10295                                            SourceLocation StartLoc,
10296                                            SourceLocation EndLoc) {
10297   OMPFlushClause *FC = nullptr;
10298   OMPClause *OrderClause = nullptr;
10299   for (OMPClause *C : Clauses) {
10300     if (C->getClauseKind() == OMPC_flush)
10301       FC = cast<OMPFlushClause>(C);
10302     else
10303       OrderClause = C;
10304   }
10305   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10306   SourceLocation MemOrderLoc;
10307   for (const OMPClause *C : Clauses) {
10308     if (C->getClauseKind() == OMPC_acq_rel ||
10309         C->getClauseKind() == OMPC_acquire ||
10310         C->getClauseKind() == OMPC_release) {
10311       if (MemOrderKind != OMPC_unknown) {
10312         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10313             << getOpenMPDirectiveName(OMPD_flush) << 1
10314             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10315         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10316             << getOpenMPClauseName(MemOrderKind);
10317       } else {
10318         MemOrderKind = C->getClauseKind();
10319         MemOrderLoc = C->getBeginLoc();
10320       }
10321     }
10322   }
10323   if (FC && OrderClause) {
10324     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10325         << getOpenMPClauseName(OrderClause->getClauseKind());
10326     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10327         << getOpenMPClauseName(OrderClause->getClauseKind());
10328     return StmtError();
10329   }
10330   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10331 }
10332 
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10333 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10334                                             SourceLocation StartLoc,
10335                                             SourceLocation EndLoc) {
10336   if (Clauses.empty()) {
10337     Diag(StartLoc, diag::err_omp_depobj_expected);
10338     return StmtError();
10339   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10340     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10341     return StmtError();
10342   }
10343   // Only depobj expression and another single clause is allowed.
10344   if (Clauses.size() > 2) {
10345     Diag(Clauses[2]->getBeginLoc(),
10346          diag::err_omp_depobj_single_clause_expected);
10347     return StmtError();
10348   } else if (Clauses.size() < 1) {
10349     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10350     return StmtError();
10351   }
10352   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10353 }
10354 
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10355 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10356                                           SourceLocation StartLoc,
10357                                           SourceLocation EndLoc) {
10358   // Check that exactly one clause is specified.
10359   if (Clauses.size() != 1) {
10360     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10361          diag::err_omp_scan_single_clause_expected);
10362     return StmtError();
10363   }
10364   // Check that scan directive is used in the scopeof the OpenMP loop body.
10365   if (Scope *S = DSAStack->getCurScope()) {
10366     Scope *ParentS = S->getParent();
10367     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10368         !ParentS->getBreakParent()->isOpenMPLoopScope())
10369       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10370                        << getOpenMPDirectiveName(OMPD_scan) << 5);
10371   }
10372   // Check that only one instance of scan directives is used in the same outer
10373   // region.
10374   if (DSAStack->doesParentHasScanDirective()) {
10375     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10376     Diag(DSAStack->getParentScanDirectiveLoc(),
10377          diag::note_omp_previous_directive)
10378         << "scan";
10379     return StmtError();
10380   }
10381   DSAStack->setParentHasScanDirective(StartLoc);
10382   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10383 }
10384 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10385 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10386                                              Stmt *AStmt,
10387                                              SourceLocation StartLoc,
10388                                              SourceLocation EndLoc) {
10389   const OMPClause *DependFound = nullptr;
10390   const OMPClause *DependSourceClause = nullptr;
10391   const OMPClause *DependSinkClause = nullptr;
10392   bool ErrorFound = false;
10393   const OMPThreadsClause *TC = nullptr;
10394   const OMPSIMDClause *SC = nullptr;
10395   for (const OMPClause *C : Clauses) {
10396     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10397       DependFound = C;
10398       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10399         if (DependSourceClause) {
10400           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10401               << getOpenMPDirectiveName(OMPD_ordered)
10402               << getOpenMPClauseName(OMPC_depend) << 2;
10403           ErrorFound = true;
10404         } else {
10405           DependSourceClause = C;
10406         }
10407         if (DependSinkClause) {
10408           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10409               << 0;
10410           ErrorFound = true;
10411         }
10412       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10413         if (DependSourceClause) {
10414           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10415               << 1;
10416           ErrorFound = true;
10417         }
10418         DependSinkClause = C;
10419       }
10420     } else if (C->getClauseKind() == OMPC_threads) {
10421       TC = cast<OMPThreadsClause>(C);
10422     } else if (C->getClauseKind() == OMPC_simd) {
10423       SC = cast<OMPSIMDClause>(C);
10424     }
10425   }
10426   if (!ErrorFound && !SC &&
10427       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
10428     // OpenMP [2.8.1,simd Construct, Restrictions]
10429     // An ordered construct with the simd clause is the only OpenMP construct
10430     // that can appear in the simd region.
10431     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10432         << (LangOpts.OpenMP >= 50 ? 1 : 0);
10433     ErrorFound = true;
10434   } else if (DependFound && (TC || SC)) {
10435     Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10436         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10437     ErrorFound = true;
10438   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
10439     Diag(DependFound->getBeginLoc(),
10440          diag::err_omp_ordered_directive_without_param);
10441     ErrorFound = true;
10442   } else if (TC || Clauses.empty()) {
10443     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
10444       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10445       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10446           << (TC != nullptr);
10447       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10448       ErrorFound = true;
10449     }
10450   }
10451   if ((!AStmt && !DependFound) || ErrorFound)
10452     return StmtError();
10453 
10454   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10455   // During execution of an iteration of a worksharing-loop or a loop nest
10456   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10457   // must not execute more than one ordered region corresponding to an ordered
10458   // construct without a depend clause.
10459   if (!DependFound) {
10460     if (DSAStack->doesParentHasOrderedDirective()) {
10461       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10462       Diag(DSAStack->getParentOrderedDirectiveLoc(),
10463            diag::note_omp_previous_directive)
10464           << "ordered";
10465       return StmtError();
10466     }
10467     DSAStack->setParentHasOrderedDirective(StartLoc);
10468   }
10469 
10470   if (AStmt) {
10471     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10472 
10473     setFunctionHasBranchProtectedScope();
10474   }
10475 
10476   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10477 }
10478 
10479 namespace {
10480 /// Helper class for checking expression in 'omp atomic [update]'
10481 /// construct.
10482 class OpenMPAtomicUpdateChecker {
10483   /// Error results for atomic update expressions.
10484   enum ExprAnalysisErrorCode {
10485     /// A statement is not an expression statement.
10486     NotAnExpression,
10487     /// Expression is not builtin binary or unary operation.
10488     NotABinaryOrUnaryExpression,
10489     /// Unary operation is not post-/pre- increment/decrement operation.
10490     NotAnUnaryIncDecExpression,
10491     /// An expression is not of scalar type.
10492     NotAScalarType,
10493     /// A binary operation is not an assignment operation.
10494     NotAnAssignmentOp,
10495     /// RHS part of the binary operation is not a binary expression.
10496     NotABinaryExpression,
10497     /// RHS part is not additive/multiplicative/shift/biwise binary
10498     /// expression.
10499     NotABinaryOperator,
10500     /// RHS binary operation does not have reference to the updated LHS
10501     /// part.
10502     NotAnUpdateExpression,
10503     /// No errors is found.
10504     NoError
10505   };
10506   /// Reference to Sema.
10507   Sema &SemaRef;
10508   /// A location for note diagnostics (when error is found).
10509   SourceLocation NoteLoc;
10510   /// 'x' lvalue part of the source atomic expression.
10511   Expr *X;
10512   /// 'expr' rvalue part of the source atomic expression.
10513   Expr *E;
10514   /// Helper expression of the form
10515   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10516   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10517   Expr *UpdateExpr;
10518   /// Is 'x' a LHS in a RHS part of full update expression. It is
10519   /// important for non-associative operations.
10520   bool IsXLHSInRHSPart;
10521   BinaryOperatorKind Op;
10522   SourceLocation OpLoc;
10523   /// true if the source expression is a postfix unary operation, false
10524   /// if it is a prefix unary operation.
10525   bool IsPostfixUpdate;
10526 
10527 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)10528   OpenMPAtomicUpdateChecker(Sema &SemaRef)
10529       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10530         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10531   /// Check specified statement that it is suitable for 'atomic update'
10532   /// constructs and extract 'x', 'expr' and Operation from the original
10533   /// expression. If DiagId and NoteId == 0, then only check is performed
10534   /// without error notification.
10535   /// \param DiagId Diagnostic which should be emitted if error is found.
10536   /// \param NoteId Diagnostic note for the main error message.
10537   /// \return true if statement is not an update expression, false otherwise.
10538   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10539   /// Return the 'x' lvalue part of the source atomic expression.
getX() const10540   Expr *getX() const { return X; }
10541   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const10542   Expr *getExpr() const { return E; }
10543   /// Return the update expression used in calculation of the updated
10544   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10545   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const10546   Expr *getUpdateExpr() const { return UpdateExpr; }
10547   /// Return true if 'x' is LHS in RHS part of full update expression,
10548   /// false otherwise.
isXLHSInRHSPart() const10549   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10550 
10551   /// true if the source expression is a postfix unary operation, false
10552   /// if it is a prefix unary operation.
isPostfixUpdate() const10553   bool isPostfixUpdate() const { return IsPostfixUpdate; }
10554 
10555 private:
10556   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10557                             unsigned NoteId = 0);
10558 };
10559 } // namespace
10560 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)10561 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10562     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10563   ExprAnalysisErrorCode ErrorFound = NoError;
10564   SourceLocation ErrorLoc, NoteLoc;
10565   SourceRange ErrorRange, NoteRange;
10566   // Allowed constructs are:
10567   //  x = x binop expr;
10568   //  x = expr binop x;
10569   if (AtomicBinOp->getOpcode() == BO_Assign) {
10570     X = AtomicBinOp->getLHS();
10571     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10572             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10573       if (AtomicInnerBinOp->isMultiplicativeOp() ||
10574           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10575           AtomicInnerBinOp->isBitwiseOp()) {
10576         Op = AtomicInnerBinOp->getOpcode();
10577         OpLoc = AtomicInnerBinOp->getOperatorLoc();
10578         Expr *LHS = AtomicInnerBinOp->getLHS();
10579         Expr *RHS = AtomicInnerBinOp->getRHS();
10580         llvm::FoldingSetNodeID XId, LHSId, RHSId;
10581         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10582                                           /*Canonical=*/true);
10583         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10584                                             /*Canonical=*/true);
10585         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10586                                             /*Canonical=*/true);
10587         if (XId == LHSId) {
10588           E = RHS;
10589           IsXLHSInRHSPart = true;
10590         } else if (XId == RHSId) {
10591           E = LHS;
10592           IsXLHSInRHSPart = false;
10593         } else {
10594           ErrorLoc = AtomicInnerBinOp->getExprLoc();
10595           ErrorRange = AtomicInnerBinOp->getSourceRange();
10596           NoteLoc = X->getExprLoc();
10597           NoteRange = X->getSourceRange();
10598           ErrorFound = NotAnUpdateExpression;
10599         }
10600       } else {
10601         ErrorLoc = AtomicInnerBinOp->getExprLoc();
10602         ErrorRange = AtomicInnerBinOp->getSourceRange();
10603         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10604         NoteRange = SourceRange(NoteLoc, NoteLoc);
10605         ErrorFound = NotABinaryOperator;
10606       }
10607     } else {
10608       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10609       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10610       ErrorFound = NotABinaryExpression;
10611     }
10612   } else {
10613     ErrorLoc = AtomicBinOp->getExprLoc();
10614     ErrorRange = AtomicBinOp->getSourceRange();
10615     NoteLoc = AtomicBinOp->getOperatorLoc();
10616     NoteRange = SourceRange(NoteLoc, NoteLoc);
10617     ErrorFound = NotAnAssignmentOp;
10618   }
10619   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10620     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10621     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10622     return true;
10623   }
10624   if (SemaRef.CurContext->isDependentContext())
10625     E = X = UpdateExpr = nullptr;
10626   return ErrorFound != NoError;
10627 }
10628 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)10629 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10630                                                unsigned NoteId) {
10631   ExprAnalysisErrorCode ErrorFound = NoError;
10632   SourceLocation ErrorLoc, NoteLoc;
10633   SourceRange ErrorRange, NoteRange;
10634   // Allowed constructs are:
10635   //  x++;
10636   //  x--;
10637   //  ++x;
10638   //  --x;
10639   //  x binop= expr;
10640   //  x = x binop expr;
10641   //  x = expr binop x;
10642   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10643     AtomicBody = AtomicBody->IgnoreParenImpCasts();
10644     if (AtomicBody->getType()->isScalarType() ||
10645         AtomicBody->isInstantiationDependent()) {
10646       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10647               AtomicBody->IgnoreParenImpCasts())) {
10648         // Check for Compound Assignment Operation
10649         Op = BinaryOperator::getOpForCompoundAssignment(
10650             AtomicCompAssignOp->getOpcode());
10651         OpLoc = AtomicCompAssignOp->getOperatorLoc();
10652         E = AtomicCompAssignOp->getRHS();
10653         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10654         IsXLHSInRHSPart = true;
10655       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10656                      AtomicBody->IgnoreParenImpCasts())) {
10657         // Check for Binary Operation
10658         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10659           return true;
10660       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10661                      AtomicBody->IgnoreParenImpCasts())) {
10662         // Check for Unary Operation
10663         if (AtomicUnaryOp->isIncrementDecrementOp()) {
10664           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10665           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10666           OpLoc = AtomicUnaryOp->getOperatorLoc();
10667           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10668           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10669           IsXLHSInRHSPart = true;
10670         } else {
10671           ErrorFound = NotAnUnaryIncDecExpression;
10672           ErrorLoc = AtomicUnaryOp->getExprLoc();
10673           ErrorRange = AtomicUnaryOp->getSourceRange();
10674           NoteLoc = AtomicUnaryOp->getOperatorLoc();
10675           NoteRange = SourceRange(NoteLoc, NoteLoc);
10676         }
10677       } else if (!AtomicBody->isInstantiationDependent()) {
10678         ErrorFound = NotABinaryOrUnaryExpression;
10679         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10680         NoteRange = ErrorRange = AtomicBody->getSourceRange();
10681       }
10682     } else {
10683       ErrorFound = NotAScalarType;
10684       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10685       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10686     }
10687   } else {
10688     ErrorFound = NotAnExpression;
10689     NoteLoc = ErrorLoc = S->getBeginLoc();
10690     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10691   }
10692   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10693     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10694     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10695     return true;
10696   }
10697   if (SemaRef.CurContext->isDependentContext())
10698     E = X = UpdateExpr = nullptr;
10699   if (ErrorFound == NoError && E && X) {
10700     // Build an update expression of form 'OpaqueValueExpr(x) binop
10701     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10702     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10703     auto *OVEX = new (SemaRef.getASTContext())
10704         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
10705     auto *OVEExpr = new (SemaRef.getASTContext())
10706         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
10707     ExprResult Update =
10708         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10709                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
10710     if (Update.isInvalid())
10711       return true;
10712     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10713                                                Sema::AA_Casting);
10714     if (Update.isInvalid())
10715       return true;
10716     UpdateExpr = Update.get();
10717   }
10718   return ErrorFound != NoError;
10719 }
10720 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10721 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10722                                             Stmt *AStmt,
10723                                             SourceLocation StartLoc,
10724                                             SourceLocation EndLoc) {
10725   // Register location of the first atomic directive.
10726   DSAStack->addAtomicDirectiveLoc(StartLoc);
10727   if (!AStmt)
10728     return StmtError();
10729 
10730   // 1.2.2 OpenMP Language Terminology
10731   // Structured block - An executable statement with a single entry at the
10732   // top and a single exit at the bottom.
10733   // The point of exit cannot be a branch out of the structured block.
10734   // longjmp() and throw() must not violate the entry/exit criteria.
10735   OpenMPClauseKind AtomicKind = OMPC_unknown;
10736   SourceLocation AtomicKindLoc;
10737   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10738   SourceLocation MemOrderLoc;
10739   for (const OMPClause *C : Clauses) {
10740     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10741         C->getClauseKind() == OMPC_update ||
10742         C->getClauseKind() == OMPC_capture) {
10743       if (AtomicKind != OMPC_unknown) {
10744         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10745             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10746         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10747             << getOpenMPClauseName(AtomicKind);
10748       } else {
10749         AtomicKind = C->getClauseKind();
10750         AtomicKindLoc = C->getBeginLoc();
10751       }
10752     }
10753     if (C->getClauseKind() == OMPC_seq_cst ||
10754         C->getClauseKind() == OMPC_acq_rel ||
10755         C->getClauseKind() == OMPC_acquire ||
10756         C->getClauseKind() == OMPC_release ||
10757         C->getClauseKind() == OMPC_relaxed) {
10758       if (MemOrderKind != OMPC_unknown) {
10759         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10760             << getOpenMPDirectiveName(OMPD_atomic) << 0
10761             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10762         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10763             << getOpenMPClauseName(MemOrderKind);
10764       } else {
10765         MemOrderKind = C->getClauseKind();
10766         MemOrderLoc = C->getBeginLoc();
10767       }
10768     }
10769   }
10770   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10771   // If atomic-clause is read then memory-order-clause must not be acq_rel or
10772   // release.
10773   // If atomic-clause is write then memory-order-clause must not be acq_rel or
10774   // acquire.
10775   // If atomic-clause is update or not present then memory-order-clause must not
10776   // be acq_rel or acquire.
10777   if ((AtomicKind == OMPC_read &&
10778        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10779       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10780         AtomicKind == OMPC_unknown) &&
10781        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10782     SourceLocation Loc = AtomicKindLoc;
10783     if (AtomicKind == OMPC_unknown)
10784       Loc = StartLoc;
10785     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10786         << getOpenMPClauseName(AtomicKind)
10787         << (AtomicKind == OMPC_unknown ? 1 : 0)
10788         << getOpenMPClauseName(MemOrderKind);
10789     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10790         << getOpenMPClauseName(MemOrderKind);
10791   }
10792 
10793   Stmt *Body = AStmt;
10794   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10795     Body = EWC->getSubExpr();
10796 
10797   Expr *X = nullptr;
10798   Expr *V = nullptr;
10799   Expr *E = nullptr;
10800   Expr *UE = nullptr;
10801   bool IsXLHSInRHSPart = false;
10802   bool IsPostfixUpdate = false;
10803   // OpenMP [2.12.6, atomic Construct]
10804   // In the next expressions:
10805   // * x and v (as applicable) are both l-value expressions with scalar type.
10806   // * During the execution of an atomic region, multiple syntactic
10807   // occurrences of x must designate the same storage location.
10808   // * Neither of v and expr (as applicable) may access the storage location
10809   // designated by x.
10810   // * Neither of x and expr (as applicable) may access the storage location
10811   // designated by v.
10812   // * expr is an expression with scalar type.
10813   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10814   // * binop, binop=, ++, and -- are not overloaded operators.
10815   // * The expression x binop expr must be numerically equivalent to x binop
10816   // (expr). This requirement is satisfied if the operators in expr have
10817   // precedence greater than binop, or by using parentheses around expr or
10818   // subexpressions of expr.
10819   // * The expression expr binop x must be numerically equivalent to (expr)
10820   // binop x. This requirement is satisfied if the operators in expr have
10821   // precedence equal to or greater than binop, or by using parentheses around
10822   // expr or subexpressions of expr.
10823   // * For forms that allow multiple occurrences of x, the number of times
10824   // that x is evaluated is unspecified.
10825   if (AtomicKind == OMPC_read) {
10826     enum {
10827       NotAnExpression,
10828       NotAnAssignmentOp,
10829       NotAScalarType,
10830       NotAnLValue,
10831       NoError
10832     } ErrorFound = NoError;
10833     SourceLocation ErrorLoc, NoteLoc;
10834     SourceRange ErrorRange, NoteRange;
10835     // If clause is read:
10836     //  v = x;
10837     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10838       const auto *AtomicBinOp =
10839           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10840       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10841         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10842         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10843         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10844             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10845           if (!X->isLValue() || !V->isLValue()) {
10846             const Expr *NotLValueExpr = X->isLValue() ? V : X;
10847             ErrorFound = NotAnLValue;
10848             ErrorLoc = AtomicBinOp->getExprLoc();
10849             ErrorRange = AtomicBinOp->getSourceRange();
10850             NoteLoc = NotLValueExpr->getExprLoc();
10851             NoteRange = NotLValueExpr->getSourceRange();
10852           }
10853         } else if (!X->isInstantiationDependent() ||
10854                    !V->isInstantiationDependent()) {
10855           const Expr *NotScalarExpr =
10856               (X->isInstantiationDependent() || X->getType()->isScalarType())
10857                   ? V
10858                   : X;
10859           ErrorFound = NotAScalarType;
10860           ErrorLoc = AtomicBinOp->getExprLoc();
10861           ErrorRange = AtomicBinOp->getSourceRange();
10862           NoteLoc = NotScalarExpr->getExprLoc();
10863           NoteRange = NotScalarExpr->getSourceRange();
10864         }
10865       } else if (!AtomicBody->isInstantiationDependent()) {
10866         ErrorFound = NotAnAssignmentOp;
10867         ErrorLoc = AtomicBody->getExprLoc();
10868         ErrorRange = AtomicBody->getSourceRange();
10869         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10870                               : AtomicBody->getExprLoc();
10871         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10872                                 : AtomicBody->getSourceRange();
10873       }
10874     } else {
10875       ErrorFound = NotAnExpression;
10876       NoteLoc = ErrorLoc = Body->getBeginLoc();
10877       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10878     }
10879     if (ErrorFound != NoError) {
10880       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10881           << ErrorRange;
10882       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10883                                                       << NoteRange;
10884       return StmtError();
10885     }
10886     if (CurContext->isDependentContext())
10887       V = X = nullptr;
10888   } else if (AtomicKind == OMPC_write) {
10889     enum {
10890       NotAnExpression,
10891       NotAnAssignmentOp,
10892       NotAScalarType,
10893       NotAnLValue,
10894       NoError
10895     } ErrorFound = NoError;
10896     SourceLocation ErrorLoc, NoteLoc;
10897     SourceRange ErrorRange, NoteRange;
10898     // If clause is write:
10899     //  x = expr;
10900     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10901       const auto *AtomicBinOp =
10902           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10903       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10904         X = AtomicBinOp->getLHS();
10905         E = AtomicBinOp->getRHS();
10906         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10907             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10908           if (!X->isLValue()) {
10909             ErrorFound = NotAnLValue;
10910             ErrorLoc = AtomicBinOp->getExprLoc();
10911             ErrorRange = AtomicBinOp->getSourceRange();
10912             NoteLoc = X->getExprLoc();
10913             NoteRange = X->getSourceRange();
10914           }
10915         } else if (!X->isInstantiationDependent() ||
10916                    !E->isInstantiationDependent()) {
10917           const Expr *NotScalarExpr =
10918               (X->isInstantiationDependent() || X->getType()->isScalarType())
10919                   ? E
10920                   : X;
10921           ErrorFound = NotAScalarType;
10922           ErrorLoc = AtomicBinOp->getExprLoc();
10923           ErrorRange = AtomicBinOp->getSourceRange();
10924           NoteLoc = NotScalarExpr->getExprLoc();
10925           NoteRange = NotScalarExpr->getSourceRange();
10926         }
10927       } else if (!AtomicBody->isInstantiationDependent()) {
10928         ErrorFound = NotAnAssignmentOp;
10929         ErrorLoc = AtomicBody->getExprLoc();
10930         ErrorRange = AtomicBody->getSourceRange();
10931         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10932                               : AtomicBody->getExprLoc();
10933         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10934                                 : AtomicBody->getSourceRange();
10935       }
10936     } else {
10937       ErrorFound = NotAnExpression;
10938       NoteLoc = ErrorLoc = Body->getBeginLoc();
10939       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10940     }
10941     if (ErrorFound != NoError) {
10942       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10943           << ErrorRange;
10944       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10945                                                       << NoteRange;
10946       return StmtError();
10947     }
10948     if (CurContext->isDependentContext())
10949       E = X = nullptr;
10950   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10951     // If clause is update:
10952     //  x++;
10953     //  x--;
10954     //  ++x;
10955     //  --x;
10956     //  x binop= expr;
10957     //  x = x binop expr;
10958     //  x = expr binop x;
10959     OpenMPAtomicUpdateChecker Checker(*this);
10960     if (Checker.checkStatement(
10961             Body, (AtomicKind == OMPC_update)
10962                       ? diag::err_omp_atomic_update_not_expression_statement
10963                       : diag::err_omp_atomic_not_expression_statement,
10964             diag::note_omp_atomic_update))
10965       return StmtError();
10966     if (!CurContext->isDependentContext()) {
10967       E = Checker.getExpr();
10968       X = Checker.getX();
10969       UE = Checker.getUpdateExpr();
10970       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10971     }
10972   } else if (AtomicKind == OMPC_capture) {
10973     enum {
10974       NotAnAssignmentOp,
10975       NotACompoundStatement,
10976       NotTwoSubstatements,
10977       NotASpecificExpression,
10978       NoError
10979     } ErrorFound = NoError;
10980     SourceLocation ErrorLoc, NoteLoc;
10981     SourceRange ErrorRange, NoteRange;
10982     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10983       // If clause is a capture:
10984       //  v = x++;
10985       //  v = x--;
10986       //  v = ++x;
10987       //  v = --x;
10988       //  v = x binop= expr;
10989       //  v = x = x binop expr;
10990       //  v = x = expr binop x;
10991       const auto *AtomicBinOp =
10992           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10993       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10994         V = AtomicBinOp->getLHS();
10995         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10996         OpenMPAtomicUpdateChecker Checker(*this);
10997         if (Checker.checkStatement(
10998                 Body, diag::err_omp_atomic_capture_not_expression_statement,
10999                 diag::note_omp_atomic_update))
11000           return StmtError();
11001         E = Checker.getExpr();
11002         X = Checker.getX();
11003         UE = Checker.getUpdateExpr();
11004         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11005         IsPostfixUpdate = Checker.isPostfixUpdate();
11006       } else if (!AtomicBody->isInstantiationDependent()) {
11007         ErrorLoc = AtomicBody->getExprLoc();
11008         ErrorRange = AtomicBody->getSourceRange();
11009         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
11010                               : AtomicBody->getExprLoc();
11011         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
11012                                 : AtomicBody->getSourceRange();
11013         ErrorFound = NotAnAssignmentOp;
11014       }
11015       if (ErrorFound != NoError) {
11016         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
11017             << ErrorRange;
11018         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11019         return StmtError();
11020       }
11021       if (CurContext->isDependentContext())
11022         UE = V = E = X = nullptr;
11023     } else {
11024       // If clause is a capture:
11025       //  { v = x; x = expr; }
11026       //  { v = x; x++; }
11027       //  { v = x; x--; }
11028       //  { v = x; ++x; }
11029       //  { v = x; --x; }
11030       //  { v = x; x binop= expr; }
11031       //  { v = x; x = x binop expr; }
11032       //  { v = x; x = expr binop x; }
11033       //  { x++; v = x; }
11034       //  { x--; v = x; }
11035       //  { ++x; v = x; }
11036       //  { --x; v = x; }
11037       //  { x binop= expr; v = x; }
11038       //  { x = x binop expr; v = x; }
11039       //  { x = expr binop x; v = x; }
11040       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
11041         // Check that this is { expr1; expr2; }
11042         if (CS->size() == 2) {
11043           Stmt *First = CS->body_front();
11044           Stmt *Second = CS->body_back();
11045           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
11046             First = EWC->getSubExpr()->IgnoreParenImpCasts();
11047           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
11048             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
11049           // Need to find what subexpression is 'v' and what is 'x'.
11050           OpenMPAtomicUpdateChecker Checker(*this);
11051           bool IsUpdateExprFound = !Checker.checkStatement(Second);
11052           BinaryOperator *BinOp = nullptr;
11053           if (IsUpdateExprFound) {
11054             BinOp = dyn_cast<BinaryOperator>(First);
11055             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
11056           }
11057           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
11058             //  { v = x; x++; }
11059             //  { v = x; x--; }
11060             //  { v = x; ++x; }
11061             //  { v = x; --x; }
11062             //  { v = x; x binop= expr; }
11063             //  { v = x; x = x binop expr; }
11064             //  { v = x; x = expr binop x; }
11065             // Check that the first expression has form v = x.
11066             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11067             llvm::FoldingSetNodeID XId, PossibleXId;
11068             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11069             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11070             IsUpdateExprFound = XId == PossibleXId;
11071             if (IsUpdateExprFound) {
11072               V = BinOp->getLHS();
11073               X = Checker.getX();
11074               E = Checker.getExpr();
11075               UE = Checker.getUpdateExpr();
11076               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11077               IsPostfixUpdate = true;
11078             }
11079           }
11080           if (!IsUpdateExprFound) {
11081             IsUpdateExprFound = !Checker.checkStatement(First);
11082             BinOp = nullptr;
11083             if (IsUpdateExprFound) {
11084               BinOp = dyn_cast<BinaryOperator>(Second);
11085               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
11086             }
11087             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
11088               //  { x++; v = x; }
11089               //  { x--; v = x; }
11090               //  { ++x; v = x; }
11091               //  { --x; v = x; }
11092               //  { x binop= expr; v = x; }
11093               //  { x = x binop expr; v = x; }
11094               //  { x = expr binop x; v = x; }
11095               // Check that the second expression has form v = x.
11096               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11097               llvm::FoldingSetNodeID XId, PossibleXId;
11098               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11099               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11100               IsUpdateExprFound = XId == PossibleXId;
11101               if (IsUpdateExprFound) {
11102                 V = BinOp->getLHS();
11103                 X = Checker.getX();
11104                 E = Checker.getExpr();
11105                 UE = Checker.getUpdateExpr();
11106                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11107                 IsPostfixUpdate = false;
11108               }
11109             }
11110           }
11111           if (!IsUpdateExprFound) {
11112             //  { v = x; x = expr; }
11113             auto *FirstExpr = dyn_cast<Expr>(First);
11114             auto *SecondExpr = dyn_cast<Expr>(Second);
11115             if (!FirstExpr || !SecondExpr ||
11116                 !(FirstExpr->isInstantiationDependent() ||
11117                   SecondExpr->isInstantiationDependent())) {
11118               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
11119               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
11120                 ErrorFound = NotAnAssignmentOp;
11121                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
11122                                                 : First->getBeginLoc();
11123                 NoteRange = ErrorRange = FirstBinOp
11124                                              ? FirstBinOp->getSourceRange()
11125                                              : SourceRange(ErrorLoc, ErrorLoc);
11126               } else {
11127                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
11128                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
11129                   ErrorFound = NotAnAssignmentOp;
11130                   NoteLoc = ErrorLoc = SecondBinOp
11131                                            ? SecondBinOp->getOperatorLoc()
11132                                            : Second->getBeginLoc();
11133                   NoteRange = ErrorRange =
11134                       SecondBinOp ? SecondBinOp->getSourceRange()
11135                                   : SourceRange(ErrorLoc, ErrorLoc);
11136                 } else {
11137                   Expr *PossibleXRHSInFirst =
11138                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
11139                   Expr *PossibleXLHSInSecond =
11140                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
11141                   llvm::FoldingSetNodeID X1Id, X2Id;
11142                   PossibleXRHSInFirst->Profile(X1Id, Context,
11143                                                /*Canonical=*/true);
11144                   PossibleXLHSInSecond->Profile(X2Id, Context,
11145                                                 /*Canonical=*/true);
11146                   IsUpdateExprFound = X1Id == X2Id;
11147                   if (IsUpdateExprFound) {
11148                     V = FirstBinOp->getLHS();
11149                     X = SecondBinOp->getLHS();
11150                     E = SecondBinOp->getRHS();
11151                     UE = nullptr;
11152                     IsXLHSInRHSPart = false;
11153                     IsPostfixUpdate = true;
11154                   } else {
11155                     ErrorFound = NotASpecificExpression;
11156                     ErrorLoc = FirstBinOp->getExprLoc();
11157                     ErrorRange = FirstBinOp->getSourceRange();
11158                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11159                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
11160                   }
11161                 }
11162               }
11163             }
11164           }
11165         } else {
11166           NoteLoc = ErrorLoc = Body->getBeginLoc();
11167           NoteRange = ErrorRange =
11168               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11169           ErrorFound = NotTwoSubstatements;
11170         }
11171       } else {
11172         NoteLoc = ErrorLoc = Body->getBeginLoc();
11173         NoteRange = ErrorRange =
11174             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11175         ErrorFound = NotACompoundStatement;
11176       }
11177       if (ErrorFound != NoError) {
11178         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11179             << ErrorRange;
11180         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11181         return StmtError();
11182       }
11183       if (CurContext->isDependentContext())
11184         UE = V = E = X = nullptr;
11185     }
11186   }
11187 
11188   setFunctionHasBranchProtectedScope();
11189 
11190   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11191                                     X, V, E, UE, IsXLHSInRHSPart,
11192                                     IsPostfixUpdate);
11193 }
11194 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11195 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11196                                             Stmt *AStmt,
11197                                             SourceLocation StartLoc,
11198                                             SourceLocation EndLoc) {
11199   if (!AStmt)
11200     return StmtError();
11201 
11202   auto *CS = cast<CapturedStmt>(AStmt);
11203   // 1.2.2 OpenMP Language Terminology
11204   // Structured block - An executable statement with a single entry at the
11205   // top and a single exit at the bottom.
11206   // The point of exit cannot be a branch out of the structured block.
11207   // longjmp() and throw() must not violate the entry/exit criteria.
11208   CS->getCapturedDecl()->setNothrow();
11209   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11210        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11211     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11212     // 1.2.2 OpenMP Language Terminology
11213     // Structured block - An executable statement with a single entry at the
11214     // top and a single exit at the bottom.
11215     // The point of exit cannot be a branch out of the structured block.
11216     // longjmp() and throw() must not violate the entry/exit criteria.
11217     CS->getCapturedDecl()->setNothrow();
11218   }
11219 
11220   // OpenMP [2.16, Nesting of Regions]
11221   // If specified, a teams construct must be contained within a target
11222   // construct. That target construct must contain no statements or directives
11223   // outside of the teams construct.
11224   if (DSAStack->hasInnerTeamsRegion()) {
11225     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11226     bool OMPTeamsFound = true;
11227     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11228       auto I = CS->body_begin();
11229       while (I != CS->body_end()) {
11230         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11231         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11232             OMPTeamsFound) {
11233 
11234           OMPTeamsFound = false;
11235           break;
11236         }
11237         ++I;
11238       }
11239       assert(I != CS->body_end() && "Not found statement");
11240       S = *I;
11241     } else {
11242       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11243       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11244     }
11245     if (!OMPTeamsFound) {
11246       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11247       Diag(DSAStack->getInnerTeamsRegionLoc(),
11248            diag::note_omp_nested_teams_construct_here);
11249       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11250           << isa<OMPExecutableDirective>(S);
11251       return StmtError();
11252     }
11253   }
11254 
11255   setFunctionHasBranchProtectedScope();
11256 
11257   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11258 }
11259 
11260 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11261 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11262                                          Stmt *AStmt, SourceLocation StartLoc,
11263                                          SourceLocation EndLoc) {
11264   if (!AStmt)
11265     return StmtError();
11266 
11267   auto *CS = cast<CapturedStmt>(AStmt);
11268   // 1.2.2 OpenMP Language Terminology
11269   // Structured block - An executable statement with a single entry at the
11270   // top and a single exit at the bottom.
11271   // The point of exit cannot be a branch out of the structured block.
11272   // longjmp() and throw() must not violate the entry/exit criteria.
11273   CS->getCapturedDecl()->setNothrow();
11274   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11275        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11276     CS = cast<CapturedStmt>(CS->getCapturedStmt());
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   }
11284 
11285   setFunctionHasBranchProtectedScope();
11286 
11287   return OMPTargetParallelDirective::Create(
11288       Context, StartLoc, EndLoc, Clauses, AStmt,
11289       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11290 }
11291 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11292 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11293     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11294     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11295   if (!AStmt)
11296     return StmtError();
11297 
11298   auto *CS = cast<CapturedStmt>(AStmt);
11299   // 1.2.2 OpenMP Language Terminology
11300   // Structured block - An executable statement with a single entry at the
11301   // top and a single exit at the bottom.
11302   // The point of exit cannot be a branch out of the structured block.
11303   // longjmp() and throw() must not violate the entry/exit criteria.
11304   CS->getCapturedDecl()->setNothrow();
11305   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11306        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11307     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11308     // 1.2.2 OpenMP Language Terminology
11309     // Structured block - An executable statement with a single entry at the
11310     // top and a single exit at the bottom.
11311     // The point of exit cannot be a branch out of the structured block.
11312     // longjmp() and throw() must not violate the entry/exit criteria.
11313     CS->getCapturedDecl()->setNothrow();
11314   }
11315 
11316   OMPLoopBasedDirective::HelperExprs B;
11317   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11318   // define the nested loops number.
11319   unsigned NestedLoopCount =
11320       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11321                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11322                       VarsWithImplicitDSA, B);
11323   if (NestedLoopCount == 0)
11324     return StmtError();
11325 
11326   assert((CurContext->isDependentContext() || B.builtAll()) &&
11327          "omp target parallel for loop exprs were not built");
11328 
11329   if (!CurContext->isDependentContext()) {
11330     // Finalize the clauses that need pre-built expressions for CodeGen.
11331     for (OMPClause *C : Clauses) {
11332       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11333         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11334                                      B.NumIterations, *this, CurScope,
11335                                      DSAStack))
11336           return StmtError();
11337     }
11338   }
11339 
11340   setFunctionHasBranchProtectedScope();
11341   return OMPTargetParallelForDirective::Create(
11342       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11343       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11344 }
11345 
11346 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)11347 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11348                        const OpenMPClauseKind K) {
11349   return llvm::any_of(
11350       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11351 }
11352 
11353 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)11354 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11355                        const Params... ClauseTypes) {
11356   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11357 }
11358 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11359 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11360                                                 Stmt *AStmt,
11361                                                 SourceLocation StartLoc,
11362                                                 SourceLocation EndLoc) {
11363   if (!AStmt)
11364     return StmtError();
11365 
11366   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11367 
11368   // OpenMP [2.12.2, target data Construct, Restrictions]
11369   // At least one map, use_device_addr or use_device_ptr clause must appear on
11370   // the directive.
11371   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11372       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11373     StringRef Expected;
11374     if (LangOpts.OpenMP < 50)
11375       Expected = "'map' or 'use_device_ptr'";
11376     else
11377       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11378     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11379         << Expected << getOpenMPDirectiveName(OMPD_target_data);
11380     return StmtError();
11381   }
11382 
11383   setFunctionHasBranchProtectedScope();
11384 
11385   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11386                                         AStmt);
11387 }
11388 
11389 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11390 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11391                                           SourceLocation StartLoc,
11392                                           SourceLocation EndLoc, Stmt *AStmt) {
11393   if (!AStmt)
11394     return StmtError();
11395 
11396   auto *CS = cast<CapturedStmt>(AStmt);
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   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11404        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11405     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11406     // 1.2.2 OpenMP Language Terminology
11407     // Structured block - An executable statement with a single entry at the
11408     // top and a single exit at the bottom.
11409     // The point of exit cannot be a branch out of the structured block.
11410     // longjmp() and throw() must not violate the entry/exit criteria.
11411     CS->getCapturedDecl()->setNothrow();
11412   }
11413 
11414   // OpenMP [2.10.2, Restrictions, p. 99]
11415   // At least one map clause must appear on the directive.
11416   if (!hasClauses(Clauses, OMPC_map)) {
11417     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11418         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11419     return StmtError();
11420   }
11421 
11422   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11423                                              AStmt);
11424 }
11425 
11426 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11427 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11428                                          SourceLocation StartLoc,
11429                                          SourceLocation EndLoc, Stmt *AStmt) {
11430   if (!AStmt)
11431     return StmtError();
11432 
11433   auto *CS = cast<CapturedStmt>(AStmt);
11434   // 1.2.2 OpenMP Language Terminology
11435   // Structured block - An executable statement with a single entry at the
11436   // top and a single exit at the bottom.
11437   // The point of exit cannot be a branch out of the structured block.
11438   // longjmp() and throw() must not violate the entry/exit criteria.
11439   CS->getCapturedDecl()->setNothrow();
11440   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11441        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11442     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11443     // 1.2.2 OpenMP Language Terminology
11444     // Structured block - An executable statement with a single entry at the
11445     // top and a single exit at the bottom.
11446     // The point of exit cannot be a branch out of the structured block.
11447     // longjmp() and throw() must not violate the entry/exit criteria.
11448     CS->getCapturedDecl()->setNothrow();
11449   }
11450 
11451   // OpenMP [2.10.3, Restrictions, p. 102]
11452   // At least one map clause must appear on the directive.
11453   if (!hasClauses(Clauses, OMPC_map)) {
11454     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11455         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11456     return StmtError();
11457   }
11458 
11459   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11460                                             AStmt);
11461 }
11462 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11463 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11464                                                   SourceLocation StartLoc,
11465                                                   SourceLocation EndLoc,
11466                                                   Stmt *AStmt) {
11467   if (!AStmt)
11468     return StmtError();
11469 
11470   auto *CS = cast<CapturedStmt>(AStmt);
11471   // 1.2.2 OpenMP Language Terminology
11472   // Structured block - An executable statement with a single entry at the
11473   // top and a single exit at the bottom.
11474   // The point of exit cannot be a branch out of the structured block.
11475   // longjmp() and throw() must not violate the entry/exit criteria.
11476   CS->getCapturedDecl()->setNothrow();
11477   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11478        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11479     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11480     // 1.2.2 OpenMP Language Terminology
11481     // Structured block - An executable statement with a single entry at the
11482     // top and a single exit at the bottom.
11483     // The point of exit cannot be a branch out of the structured block.
11484     // longjmp() and throw() must not violate the entry/exit criteria.
11485     CS->getCapturedDecl()->setNothrow();
11486   }
11487 
11488   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11489     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11490     return StmtError();
11491   }
11492   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11493                                           AStmt);
11494 }
11495 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11496 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11497                                            Stmt *AStmt, SourceLocation StartLoc,
11498                                            SourceLocation EndLoc) {
11499   if (!AStmt)
11500     return StmtError();
11501 
11502   auto *CS = cast<CapturedStmt>(AStmt);
11503   // 1.2.2 OpenMP Language Terminology
11504   // Structured block - An executable statement with a single entry at the
11505   // top and a single exit at the bottom.
11506   // The point of exit cannot be a branch out of the structured block.
11507   // longjmp() and throw() must not violate the entry/exit criteria.
11508   CS->getCapturedDecl()->setNothrow();
11509 
11510   setFunctionHasBranchProtectedScope();
11511 
11512   DSAStack->setParentTeamsRegionLoc(StartLoc);
11513 
11514   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11515 }
11516 
11517 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11518 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11519                                             SourceLocation EndLoc,
11520                                             OpenMPDirectiveKind CancelRegion) {
11521   if (DSAStack->isParentNowaitRegion()) {
11522     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11523     return StmtError();
11524   }
11525   if (DSAStack->isParentOrderedRegion()) {
11526     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11527     return StmtError();
11528   }
11529   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11530                                                CancelRegion);
11531 }
11532 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11533 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11534                                             SourceLocation StartLoc,
11535                                             SourceLocation EndLoc,
11536                                             OpenMPDirectiveKind CancelRegion) {
11537   if (DSAStack->isParentNowaitRegion()) {
11538     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11539     return StmtError();
11540   }
11541   if (DSAStack->isParentOrderedRegion()) {
11542     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11543     return StmtError();
11544   }
11545   DSAStack->setParentCancelRegion(/*Cancel=*/true);
11546   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11547                                     CancelRegion);
11548 }
11549 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)11550 static bool checkReductionClauseWithNogroup(Sema &S,
11551                                             ArrayRef<OMPClause *> Clauses) {
11552   const OMPClause *ReductionClause = nullptr;
11553   const OMPClause *NogroupClause = nullptr;
11554   for (const OMPClause *C : Clauses) {
11555     if (C->getClauseKind() == OMPC_reduction) {
11556       ReductionClause = C;
11557       if (NogroupClause)
11558         break;
11559       continue;
11560     }
11561     if (C->getClauseKind() == OMPC_nogroup) {
11562       NogroupClause = C;
11563       if (ReductionClause)
11564         break;
11565       continue;
11566     }
11567   }
11568   if (ReductionClause && NogroupClause) {
11569     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11570         << SourceRange(NogroupClause->getBeginLoc(),
11571                        NogroupClause->getEndLoc());
11572     return true;
11573   }
11574   return false;
11575 }
11576 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11577 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11578     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11579     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11580   if (!AStmt)
11581     return StmtError();
11582 
11583   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11584   OMPLoopBasedDirective::HelperExprs B;
11585   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11586   // define the nested loops number.
11587   unsigned NestedLoopCount =
11588       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11589                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11590                       VarsWithImplicitDSA, B);
11591   if (NestedLoopCount == 0)
11592     return StmtError();
11593 
11594   assert((CurContext->isDependentContext() || B.builtAll()) &&
11595          "omp for loop exprs were not built");
11596 
11597   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11598   // The grainsize clause and num_tasks clause are mutually exclusive and may
11599   // not appear on the same taskloop directive.
11600   if (checkMutuallyExclusiveClauses(*this, Clauses,
11601                                     {OMPC_grainsize, OMPC_num_tasks}))
11602     return StmtError();
11603   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11604   // If a reduction clause is present on the taskloop directive, the nogroup
11605   // clause must not be specified.
11606   if (checkReductionClauseWithNogroup(*this, Clauses))
11607     return StmtError();
11608 
11609   setFunctionHasBranchProtectedScope();
11610   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11611                                       NestedLoopCount, Clauses, AStmt, B,
11612                                       DSAStack->isCancelRegion());
11613 }
11614 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11615 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11616     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11617     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11618   if (!AStmt)
11619     return StmtError();
11620 
11621   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11622   OMPLoopBasedDirective::HelperExprs B;
11623   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11624   // define the nested loops number.
11625   unsigned NestedLoopCount =
11626       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11627                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11628                       VarsWithImplicitDSA, B);
11629   if (NestedLoopCount == 0)
11630     return StmtError();
11631 
11632   assert((CurContext->isDependentContext() || B.builtAll()) &&
11633          "omp for loop exprs were not built");
11634 
11635   if (!CurContext->isDependentContext()) {
11636     // Finalize the clauses that need pre-built expressions for CodeGen.
11637     for (OMPClause *C : Clauses) {
11638       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11639         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11640                                      B.NumIterations, *this, CurScope,
11641                                      DSAStack))
11642           return StmtError();
11643     }
11644   }
11645 
11646   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11647   // The grainsize clause and num_tasks clause are mutually exclusive and may
11648   // not appear on the same taskloop directive.
11649   if (checkMutuallyExclusiveClauses(*this, Clauses,
11650                                     {OMPC_grainsize, OMPC_num_tasks}))
11651     return StmtError();
11652   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11653   // If a reduction clause is present on the taskloop directive, the nogroup
11654   // clause must not be specified.
11655   if (checkReductionClauseWithNogroup(*this, Clauses))
11656     return StmtError();
11657   if (checkSimdlenSafelenSpecified(*this, Clauses))
11658     return StmtError();
11659 
11660   setFunctionHasBranchProtectedScope();
11661   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11662                                           NestedLoopCount, Clauses, AStmt, B);
11663 }
11664 
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11665 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11666     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11667     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11668   if (!AStmt)
11669     return StmtError();
11670 
11671   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11672   OMPLoopBasedDirective::HelperExprs B;
11673   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11674   // define the nested loops number.
11675   unsigned NestedLoopCount =
11676       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11677                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11678                       VarsWithImplicitDSA, B);
11679   if (NestedLoopCount == 0)
11680     return StmtError();
11681 
11682   assert((CurContext->isDependentContext() || B.builtAll()) &&
11683          "omp for loop exprs were not built");
11684 
11685   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11686   // The grainsize clause and num_tasks clause are mutually exclusive and may
11687   // not appear on the same taskloop directive.
11688   if (checkMutuallyExclusiveClauses(*this, Clauses,
11689                                     {OMPC_grainsize, OMPC_num_tasks}))
11690     return StmtError();
11691   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11692   // If a reduction clause is present on the taskloop directive, the nogroup
11693   // clause must not be specified.
11694   if (checkReductionClauseWithNogroup(*this, Clauses))
11695     return StmtError();
11696 
11697   setFunctionHasBranchProtectedScope();
11698   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11699                                             NestedLoopCount, Clauses, AStmt, B,
11700                                             DSAStack->isCancelRegion());
11701 }
11702 
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11703 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11704     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11705     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11706   if (!AStmt)
11707     return StmtError();
11708 
11709   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11710   OMPLoopBasedDirective::HelperExprs B;
11711   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11712   // define the nested loops number.
11713   unsigned NestedLoopCount =
11714       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11715                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11716                       VarsWithImplicitDSA, B);
11717   if (NestedLoopCount == 0)
11718     return StmtError();
11719 
11720   assert((CurContext->isDependentContext() || B.builtAll()) &&
11721          "omp for loop exprs were not built");
11722 
11723   if (!CurContext->isDependentContext()) {
11724     // Finalize the clauses that need pre-built expressions for CodeGen.
11725     for (OMPClause *C : Clauses) {
11726       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11727         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11728                                      B.NumIterations, *this, CurScope,
11729                                      DSAStack))
11730           return StmtError();
11731     }
11732   }
11733 
11734   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11735   // The grainsize clause and num_tasks clause are mutually exclusive and may
11736   // not appear on the same taskloop directive.
11737   if (checkMutuallyExclusiveClauses(*this, Clauses,
11738                                     {OMPC_grainsize, OMPC_num_tasks}))
11739     return StmtError();
11740   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11741   // If a reduction clause is present on the taskloop directive, the nogroup
11742   // clause must not be specified.
11743   if (checkReductionClauseWithNogroup(*this, Clauses))
11744     return StmtError();
11745   if (checkSimdlenSafelenSpecified(*this, Clauses))
11746     return StmtError();
11747 
11748   setFunctionHasBranchProtectedScope();
11749   return OMPMasterTaskLoopSimdDirective::Create(
11750       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11751 }
11752 
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11753 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11754     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11755     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11756   if (!AStmt)
11757     return StmtError();
11758 
11759   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11760   auto *CS = cast<CapturedStmt>(AStmt);
11761   // 1.2.2 OpenMP Language Terminology
11762   // Structured block - An executable statement with a single entry at the
11763   // top and a single exit at the bottom.
11764   // The point of exit cannot be a branch out of the structured block.
11765   // longjmp() and throw() must not violate the entry/exit criteria.
11766   CS->getCapturedDecl()->setNothrow();
11767   for (int ThisCaptureLevel =
11768            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11769        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11770     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11771     // 1.2.2 OpenMP Language Terminology
11772     // Structured block - An executable statement with a single entry at the
11773     // top and a single exit at the bottom.
11774     // The point of exit cannot be a branch out of the structured block.
11775     // longjmp() and throw() must not violate the entry/exit criteria.
11776     CS->getCapturedDecl()->setNothrow();
11777   }
11778 
11779   OMPLoopBasedDirective::HelperExprs B;
11780   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11781   // define the nested loops number.
11782   unsigned NestedLoopCount = checkOpenMPLoop(
11783       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11784       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11785       VarsWithImplicitDSA, B);
11786   if (NestedLoopCount == 0)
11787     return StmtError();
11788 
11789   assert((CurContext->isDependentContext() || B.builtAll()) &&
11790          "omp for loop exprs were not built");
11791 
11792   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11793   // The grainsize clause and num_tasks clause are mutually exclusive and may
11794   // not appear on the same taskloop directive.
11795   if (checkMutuallyExclusiveClauses(*this, Clauses,
11796                                     {OMPC_grainsize, OMPC_num_tasks}))
11797     return StmtError();
11798   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11799   // If a reduction clause is present on the taskloop directive, the nogroup
11800   // clause must not be specified.
11801   if (checkReductionClauseWithNogroup(*this, Clauses))
11802     return StmtError();
11803 
11804   setFunctionHasBranchProtectedScope();
11805   return OMPParallelMasterTaskLoopDirective::Create(
11806       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11807       DSAStack->isCancelRegion());
11808 }
11809 
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11810 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11811     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11812     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11813   if (!AStmt)
11814     return StmtError();
11815 
11816   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11817   auto *CS = cast<CapturedStmt>(AStmt);
11818   // 1.2.2 OpenMP Language Terminology
11819   // Structured block - An executable statement with a single entry at the
11820   // top and a single exit at the bottom.
11821   // The point of exit cannot be a branch out of the structured block.
11822   // longjmp() and throw() must not violate the entry/exit criteria.
11823   CS->getCapturedDecl()->setNothrow();
11824   for (int ThisCaptureLevel =
11825            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11826        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11827     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11828     // 1.2.2 OpenMP Language Terminology
11829     // Structured block - An executable statement with a single entry at the
11830     // top and a single exit at the bottom.
11831     // The point of exit cannot be a branch out of the structured block.
11832     // longjmp() and throw() must not violate the entry/exit criteria.
11833     CS->getCapturedDecl()->setNothrow();
11834   }
11835 
11836   OMPLoopBasedDirective::HelperExprs B;
11837   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11838   // define the nested loops number.
11839   unsigned NestedLoopCount = checkOpenMPLoop(
11840       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11841       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11842       VarsWithImplicitDSA, B);
11843   if (NestedLoopCount == 0)
11844     return StmtError();
11845 
11846   assert((CurContext->isDependentContext() || B.builtAll()) &&
11847          "omp for loop exprs were not built");
11848 
11849   if (!CurContext->isDependentContext()) {
11850     // Finalize the clauses that need pre-built expressions for CodeGen.
11851     for (OMPClause *C : Clauses) {
11852       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11853         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11854                                      B.NumIterations, *this, CurScope,
11855                                      DSAStack))
11856           return StmtError();
11857     }
11858   }
11859 
11860   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11861   // The grainsize clause and num_tasks clause are mutually exclusive and may
11862   // not appear on the same taskloop directive.
11863   if (checkMutuallyExclusiveClauses(*this, Clauses,
11864                                     {OMPC_grainsize, OMPC_num_tasks}))
11865     return StmtError();
11866   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11867   // If a reduction clause is present on the taskloop directive, the nogroup
11868   // clause must not be specified.
11869   if (checkReductionClauseWithNogroup(*this, Clauses))
11870     return StmtError();
11871   if (checkSimdlenSafelenSpecified(*this, Clauses))
11872     return StmtError();
11873 
11874   setFunctionHasBranchProtectedScope();
11875   return OMPParallelMasterTaskLoopSimdDirective::Create(
11876       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11877 }
11878 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11879 StmtResult Sema::ActOnOpenMPDistributeDirective(
11880     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11881     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11882   if (!AStmt)
11883     return StmtError();
11884 
11885   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11886   OMPLoopBasedDirective::HelperExprs B;
11887   // In presence of clause 'collapse' with number of loops, it will
11888   // define the nested loops number.
11889   unsigned NestedLoopCount =
11890       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11891                       nullptr /*ordered not a clause on distribute*/, AStmt,
11892                       *this, *DSAStack, VarsWithImplicitDSA, B);
11893   if (NestedLoopCount == 0)
11894     return StmtError();
11895 
11896   assert((CurContext->isDependentContext() || B.builtAll()) &&
11897          "omp for loop exprs were not built");
11898 
11899   setFunctionHasBranchProtectedScope();
11900   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11901                                         NestedLoopCount, Clauses, AStmt, B);
11902 }
11903 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11904 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11905     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11906     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11907   if (!AStmt)
11908     return StmtError();
11909 
11910   auto *CS = cast<CapturedStmt>(AStmt);
11911   // 1.2.2 OpenMP Language Terminology
11912   // Structured block - An executable statement with a single entry at the
11913   // top and a single exit at the bottom.
11914   // The point of exit cannot be a branch out of the structured block.
11915   // longjmp() and throw() must not violate the entry/exit criteria.
11916   CS->getCapturedDecl()->setNothrow();
11917   for (int ThisCaptureLevel =
11918            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11919        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11920     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11921     // 1.2.2 OpenMP Language Terminology
11922     // Structured block - An executable statement with a single entry at the
11923     // top and a single exit at the bottom.
11924     // The point of exit cannot be a branch out of the structured block.
11925     // longjmp() and throw() must not violate the entry/exit criteria.
11926     CS->getCapturedDecl()->setNothrow();
11927   }
11928 
11929   OMPLoopBasedDirective::HelperExprs B;
11930   // In presence of clause 'collapse' with number of loops, it will
11931   // define the nested loops number.
11932   unsigned NestedLoopCount = checkOpenMPLoop(
11933       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11934       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11935       VarsWithImplicitDSA, B);
11936   if (NestedLoopCount == 0)
11937     return StmtError();
11938 
11939   assert((CurContext->isDependentContext() || B.builtAll()) &&
11940          "omp for loop exprs were not built");
11941 
11942   setFunctionHasBranchProtectedScope();
11943   return OMPDistributeParallelForDirective::Create(
11944       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11945       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11946 }
11947 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11948 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11949     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11950     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11951   if (!AStmt)
11952     return StmtError();
11953 
11954   auto *CS = cast<CapturedStmt>(AStmt);
11955   // 1.2.2 OpenMP Language Terminology
11956   // Structured block - An executable statement with a single entry at the
11957   // top and a single exit at the bottom.
11958   // The point of exit cannot be a branch out of the structured block.
11959   // longjmp() and throw() must not violate the entry/exit criteria.
11960   CS->getCapturedDecl()->setNothrow();
11961   for (int ThisCaptureLevel =
11962            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11963        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11964     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11965     // 1.2.2 OpenMP Language Terminology
11966     // Structured block - An executable statement with a single entry at the
11967     // top and a single exit at the bottom.
11968     // The point of exit cannot be a branch out of the structured block.
11969     // longjmp() and throw() must not violate the entry/exit criteria.
11970     CS->getCapturedDecl()->setNothrow();
11971   }
11972 
11973   OMPLoopBasedDirective::HelperExprs B;
11974   // In presence of clause 'collapse' with number of loops, it will
11975   // define the nested loops number.
11976   unsigned NestedLoopCount = checkOpenMPLoop(
11977       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11978       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11979       VarsWithImplicitDSA, B);
11980   if (NestedLoopCount == 0)
11981     return StmtError();
11982 
11983   assert((CurContext->isDependentContext() || B.builtAll()) &&
11984          "omp for loop exprs were not built");
11985 
11986   if (!CurContext->isDependentContext()) {
11987     // Finalize the clauses that need pre-built expressions for CodeGen.
11988     for (OMPClause *C : Clauses) {
11989       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11990         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11991                                      B.NumIterations, *this, CurScope,
11992                                      DSAStack))
11993           return StmtError();
11994     }
11995   }
11996 
11997   if (checkSimdlenSafelenSpecified(*this, Clauses))
11998     return StmtError();
11999 
12000   setFunctionHasBranchProtectedScope();
12001   return OMPDistributeParallelForSimdDirective::Create(
12002       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12003 }
12004 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12005 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
12006     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12007     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12008   if (!AStmt)
12009     return StmtError();
12010 
12011   auto *CS = cast<CapturedStmt>(AStmt);
12012   // 1.2.2 OpenMP Language Terminology
12013   // Structured block - An executable statement with a single entry at the
12014   // top and a single exit at the bottom.
12015   // The point of exit cannot be a branch out of the structured block.
12016   // longjmp() and throw() must not violate the entry/exit criteria.
12017   CS->getCapturedDecl()->setNothrow();
12018   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
12019        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12020     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12021     // 1.2.2 OpenMP Language Terminology
12022     // Structured block - An executable statement with a single entry at the
12023     // top and a single exit at the bottom.
12024     // The point of exit cannot be a branch out of the structured block.
12025     // longjmp() and throw() must not violate the entry/exit criteria.
12026     CS->getCapturedDecl()->setNothrow();
12027   }
12028 
12029   OMPLoopBasedDirective::HelperExprs B;
12030   // In presence of clause 'collapse' with number of loops, it will
12031   // define the nested loops number.
12032   unsigned NestedLoopCount =
12033       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
12034                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12035                       *DSAStack, VarsWithImplicitDSA, B);
12036   if (NestedLoopCount == 0)
12037     return StmtError();
12038 
12039   assert((CurContext->isDependentContext() || B.builtAll()) &&
12040          "omp for loop exprs were not built");
12041 
12042   if (!CurContext->isDependentContext()) {
12043     // Finalize the clauses that need pre-built expressions for CodeGen.
12044     for (OMPClause *C : Clauses) {
12045       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12046         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12047                                      B.NumIterations, *this, CurScope,
12048                                      DSAStack))
12049           return StmtError();
12050     }
12051   }
12052 
12053   if (checkSimdlenSafelenSpecified(*this, Clauses))
12054     return StmtError();
12055 
12056   setFunctionHasBranchProtectedScope();
12057   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
12058                                             NestedLoopCount, Clauses, AStmt, B);
12059 }
12060 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12061 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
12062     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12063     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12064   if (!AStmt)
12065     return StmtError();
12066 
12067   auto *CS = cast<CapturedStmt>(AStmt);
12068   // 1.2.2 OpenMP Language Terminology
12069   // Structured block - An executable statement with a single entry at the
12070   // top and a single exit at the bottom.
12071   // The point of exit cannot be a branch out of the structured block.
12072   // longjmp() and throw() must not violate the entry/exit criteria.
12073   CS->getCapturedDecl()->setNothrow();
12074   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12075        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12076     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12077     // 1.2.2 OpenMP Language Terminology
12078     // Structured block - An executable statement with a single entry at the
12079     // top and a single exit at the bottom.
12080     // The point of exit cannot be a branch out of the structured block.
12081     // longjmp() and throw() must not violate the entry/exit criteria.
12082     CS->getCapturedDecl()->setNothrow();
12083   }
12084 
12085   OMPLoopBasedDirective::HelperExprs B;
12086   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12087   // define the nested loops number.
12088   unsigned NestedLoopCount = checkOpenMPLoop(
12089       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
12090       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12091       VarsWithImplicitDSA, B);
12092   if (NestedLoopCount == 0)
12093     return StmtError();
12094 
12095   assert((CurContext->isDependentContext() || B.builtAll()) &&
12096          "omp target parallel for simd loop exprs were not built");
12097 
12098   if (!CurContext->isDependentContext()) {
12099     // Finalize the clauses that need pre-built expressions for CodeGen.
12100     for (OMPClause *C : Clauses) {
12101       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12102         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12103                                      B.NumIterations, *this, CurScope,
12104                                      DSAStack))
12105           return StmtError();
12106     }
12107   }
12108   if (checkSimdlenSafelenSpecified(*this, Clauses))
12109     return StmtError();
12110 
12111   setFunctionHasBranchProtectedScope();
12112   return OMPTargetParallelForSimdDirective::Create(
12113       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12114 }
12115 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12116 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
12117     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12118     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12119   if (!AStmt)
12120     return StmtError();
12121 
12122   auto *CS = cast<CapturedStmt>(AStmt);
12123   // 1.2.2 OpenMP Language Terminology
12124   // Structured block - An executable statement with a single entry at the
12125   // top and a single exit at the bottom.
12126   // The point of exit cannot be a branch out of the structured block.
12127   // longjmp() and throw() must not violate the entry/exit criteria.
12128   CS->getCapturedDecl()->setNothrow();
12129   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
12130        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12131     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12132     // 1.2.2 OpenMP Language Terminology
12133     // Structured block - An executable statement with a single entry at the
12134     // top and a single exit at the bottom.
12135     // The point of exit cannot be a branch out of the structured block.
12136     // longjmp() and throw() must not violate the entry/exit criteria.
12137     CS->getCapturedDecl()->setNothrow();
12138   }
12139 
12140   OMPLoopBasedDirective::HelperExprs B;
12141   // In presence of clause 'collapse' with number of loops, it will define the
12142   // nested loops number.
12143   unsigned NestedLoopCount =
12144       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12145                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12146                       VarsWithImplicitDSA, B);
12147   if (NestedLoopCount == 0)
12148     return StmtError();
12149 
12150   assert((CurContext->isDependentContext() || B.builtAll()) &&
12151          "omp target simd loop exprs were not built");
12152 
12153   if (!CurContext->isDependentContext()) {
12154     // Finalize the clauses that need pre-built expressions for CodeGen.
12155     for (OMPClause *C : Clauses) {
12156       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12157         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12158                                      B.NumIterations, *this, CurScope,
12159                                      DSAStack))
12160           return StmtError();
12161     }
12162   }
12163 
12164   if (checkSimdlenSafelenSpecified(*this, Clauses))
12165     return StmtError();
12166 
12167   setFunctionHasBranchProtectedScope();
12168   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12169                                         NestedLoopCount, Clauses, AStmt, B);
12170 }
12171 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12172 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12173     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12174     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12175   if (!AStmt)
12176     return StmtError();
12177 
12178   auto *CS = cast<CapturedStmt>(AStmt);
12179   // 1.2.2 OpenMP Language Terminology
12180   // Structured block - An executable statement with a single entry at the
12181   // top and a single exit at the bottom.
12182   // The point of exit cannot be a branch out of the structured block.
12183   // longjmp() and throw() must not violate the entry/exit criteria.
12184   CS->getCapturedDecl()->setNothrow();
12185   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12186        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12187     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12188     // 1.2.2 OpenMP Language Terminology
12189     // Structured block - An executable statement with a single entry at the
12190     // top and a single exit at the bottom.
12191     // The point of exit cannot be a branch out of the structured block.
12192     // longjmp() and throw() must not violate the entry/exit criteria.
12193     CS->getCapturedDecl()->setNothrow();
12194   }
12195 
12196   OMPLoopBasedDirective::HelperExprs B;
12197   // In presence of clause 'collapse' with number of loops, it will
12198   // define the nested loops number.
12199   unsigned NestedLoopCount =
12200       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12201                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12202                       *DSAStack, VarsWithImplicitDSA, B);
12203   if (NestedLoopCount == 0)
12204     return StmtError();
12205 
12206   assert((CurContext->isDependentContext() || B.builtAll()) &&
12207          "omp teams distribute loop exprs were not built");
12208 
12209   setFunctionHasBranchProtectedScope();
12210 
12211   DSAStack->setParentTeamsRegionLoc(StartLoc);
12212 
12213   return OMPTeamsDistributeDirective::Create(
12214       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12215 }
12216 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12217 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12218     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12219     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12220   if (!AStmt)
12221     return StmtError();
12222 
12223   auto *CS = cast<CapturedStmt>(AStmt);
12224   // 1.2.2 OpenMP Language Terminology
12225   // Structured block - An executable statement with a single entry at the
12226   // top and a single exit at the bottom.
12227   // The point of exit cannot be a branch out of the structured block.
12228   // longjmp() and throw() must not violate the entry/exit criteria.
12229   CS->getCapturedDecl()->setNothrow();
12230   for (int ThisCaptureLevel =
12231            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12232        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12233     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12234     // 1.2.2 OpenMP Language Terminology
12235     // Structured block - An executable statement with a single entry at the
12236     // top and a single exit at the bottom.
12237     // The point of exit cannot be a branch out of the structured block.
12238     // longjmp() and throw() must not violate the entry/exit criteria.
12239     CS->getCapturedDecl()->setNothrow();
12240   }
12241 
12242   OMPLoopBasedDirective::HelperExprs B;
12243   // In presence of clause 'collapse' with number of loops, it will
12244   // define the nested loops number.
12245   unsigned NestedLoopCount = checkOpenMPLoop(
12246       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12247       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12248       VarsWithImplicitDSA, B);
12249 
12250   if (NestedLoopCount == 0)
12251     return StmtError();
12252 
12253   assert((CurContext->isDependentContext() || B.builtAll()) &&
12254          "omp teams distribute simd loop exprs were not built");
12255 
12256   if (!CurContext->isDependentContext()) {
12257     // Finalize the clauses that need pre-built expressions for CodeGen.
12258     for (OMPClause *C : Clauses) {
12259       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12260         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12261                                      B.NumIterations, *this, CurScope,
12262                                      DSAStack))
12263           return StmtError();
12264     }
12265   }
12266 
12267   if (checkSimdlenSafelenSpecified(*this, Clauses))
12268     return StmtError();
12269 
12270   setFunctionHasBranchProtectedScope();
12271 
12272   DSAStack->setParentTeamsRegionLoc(StartLoc);
12273 
12274   return OMPTeamsDistributeSimdDirective::Create(
12275       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12276 }
12277 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12278 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12279     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12280     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12281   if (!AStmt)
12282     return StmtError();
12283 
12284   auto *CS = cast<CapturedStmt>(AStmt);
12285   // 1.2.2 OpenMP Language Terminology
12286   // Structured block - An executable statement with a single entry at the
12287   // top and a single exit at the bottom.
12288   // The point of exit cannot be a branch out of the structured block.
12289   // longjmp() and throw() must not violate the entry/exit criteria.
12290   CS->getCapturedDecl()->setNothrow();
12291 
12292   for (int ThisCaptureLevel =
12293            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12294        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12295     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12296     // 1.2.2 OpenMP Language Terminology
12297     // Structured block - An executable statement with a single entry at the
12298     // top and a single exit at the bottom.
12299     // The point of exit cannot be a branch out of the structured block.
12300     // longjmp() and throw() must not violate the entry/exit criteria.
12301     CS->getCapturedDecl()->setNothrow();
12302   }
12303 
12304   OMPLoopBasedDirective::HelperExprs B;
12305   // In presence of clause 'collapse' with number of loops, it will
12306   // define the nested loops number.
12307   unsigned NestedLoopCount = checkOpenMPLoop(
12308       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12309       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12310       VarsWithImplicitDSA, B);
12311 
12312   if (NestedLoopCount == 0)
12313     return StmtError();
12314 
12315   assert((CurContext->isDependentContext() || B.builtAll()) &&
12316          "omp for loop exprs were not built");
12317 
12318   if (!CurContext->isDependentContext()) {
12319     // Finalize the clauses that need pre-built expressions for CodeGen.
12320     for (OMPClause *C : Clauses) {
12321       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12322         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12323                                      B.NumIterations, *this, CurScope,
12324                                      DSAStack))
12325           return StmtError();
12326     }
12327   }
12328 
12329   if (checkSimdlenSafelenSpecified(*this, Clauses))
12330     return StmtError();
12331 
12332   setFunctionHasBranchProtectedScope();
12333 
12334   DSAStack->setParentTeamsRegionLoc(StartLoc);
12335 
12336   return OMPTeamsDistributeParallelForSimdDirective::Create(
12337       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12338 }
12339 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12340 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12341     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12342     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12343   if (!AStmt)
12344     return StmtError();
12345 
12346   auto *CS = cast<CapturedStmt>(AStmt);
12347   // 1.2.2 OpenMP Language Terminology
12348   // Structured block - An executable statement with a single entry at the
12349   // top and a single exit at the bottom.
12350   // The point of exit cannot be a branch out of the structured block.
12351   // longjmp() and throw() must not violate the entry/exit criteria.
12352   CS->getCapturedDecl()->setNothrow();
12353 
12354   for (int ThisCaptureLevel =
12355            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12356        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12357     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12358     // 1.2.2 OpenMP Language Terminology
12359     // Structured block - An executable statement with a single entry at the
12360     // top and a single exit at the bottom.
12361     // The point of exit cannot be a branch out of the structured block.
12362     // longjmp() and throw() must not violate the entry/exit criteria.
12363     CS->getCapturedDecl()->setNothrow();
12364   }
12365 
12366   OMPLoopBasedDirective::HelperExprs B;
12367   // In presence of clause 'collapse' with number of loops, it will
12368   // define the nested loops number.
12369   unsigned NestedLoopCount = checkOpenMPLoop(
12370       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12371       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12372       VarsWithImplicitDSA, B);
12373 
12374   if (NestedLoopCount == 0)
12375     return StmtError();
12376 
12377   assert((CurContext->isDependentContext() || B.builtAll()) &&
12378          "omp for loop exprs were not built");
12379 
12380   setFunctionHasBranchProtectedScope();
12381 
12382   DSAStack->setParentTeamsRegionLoc(StartLoc);
12383 
12384   return OMPTeamsDistributeParallelForDirective::Create(
12385       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12386       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12387 }
12388 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12389 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12390                                                  Stmt *AStmt,
12391                                                  SourceLocation StartLoc,
12392                                                  SourceLocation EndLoc) {
12393   if (!AStmt)
12394     return StmtError();
12395 
12396   auto *CS = cast<CapturedStmt>(AStmt);
12397   // 1.2.2 OpenMP Language Terminology
12398   // Structured block - An executable statement with a single entry at the
12399   // top and a single exit at the bottom.
12400   // The point of exit cannot be a branch out of the structured block.
12401   // longjmp() and throw() must not violate the entry/exit criteria.
12402   CS->getCapturedDecl()->setNothrow();
12403 
12404   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12405        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12406     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12407     // 1.2.2 OpenMP Language Terminology
12408     // Structured block - An executable statement with a single entry at the
12409     // top and a single exit at the bottom.
12410     // The point of exit cannot be a branch out of the structured block.
12411     // longjmp() and throw() must not violate the entry/exit criteria.
12412     CS->getCapturedDecl()->setNothrow();
12413   }
12414   setFunctionHasBranchProtectedScope();
12415 
12416   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12417                                          AStmt);
12418 }
12419 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12420 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12421     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12422     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12423   if (!AStmt)
12424     return StmtError();
12425 
12426   auto *CS = cast<CapturedStmt>(AStmt);
12427   // 1.2.2 OpenMP Language Terminology
12428   // Structured block - An executable statement with a single entry at the
12429   // top and a single exit at the bottom.
12430   // The point of exit cannot be a branch out of the structured block.
12431   // longjmp() and throw() must not violate the entry/exit criteria.
12432   CS->getCapturedDecl()->setNothrow();
12433   for (int ThisCaptureLevel =
12434            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12435        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12436     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12437     // 1.2.2 OpenMP Language Terminology
12438     // Structured block - An executable statement with a single entry at the
12439     // top and a single exit at the bottom.
12440     // The point of exit cannot be a branch out of the structured block.
12441     // longjmp() and throw() must not violate the entry/exit criteria.
12442     CS->getCapturedDecl()->setNothrow();
12443   }
12444 
12445   OMPLoopBasedDirective::HelperExprs B;
12446   // In presence of clause 'collapse' with number of loops, it will
12447   // define the nested loops number.
12448   unsigned NestedLoopCount = checkOpenMPLoop(
12449       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12450       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12451       VarsWithImplicitDSA, B);
12452   if (NestedLoopCount == 0)
12453     return StmtError();
12454 
12455   assert((CurContext->isDependentContext() || B.builtAll()) &&
12456          "omp target teams distribute loop exprs were not built");
12457 
12458   setFunctionHasBranchProtectedScope();
12459   return OMPTargetTeamsDistributeDirective::Create(
12460       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12461 }
12462 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12463 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12464     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12465     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12466   if (!AStmt)
12467     return StmtError();
12468 
12469   auto *CS = cast<CapturedStmt>(AStmt);
12470   // 1.2.2 OpenMP Language Terminology
12471   // Structured block - An executable statement with a single entry at the
12472   // top and a single exit at the bottom.
12473   // The point of exit cannot be a branch out of the structured block.
12474   // longjmp() and throw() must not violate the entry/exit criteria.
12475   CS->getCapturedDecl()->setNothrow();
12476   for (int ThisCaptureLevel =
12477            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12478        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12479     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12480     // 1.2.2 OpenMP Language Terminology
12481     // Structured block - An executable statement with a single entry at the
12482     // top and a single exit at the bottom.
12483     // The point of exit cannot be a branch out of the structured block.
12484     // longjmp() and throw() must not violate the entry/exit criteria.
12485     CS->getCapturedDecl()->setNothrow();
12486   }
12487 
12488   OMPLoopBasedDirective::HelperExprs B;
12489   // In presence of clause 'collapse' with number of loops, it will
12490   // define the nested loops number.
12491   unsigned NestedLoopCount = checkOpenMPLoop(
12492       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12493       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12494       VarsWithImplicitDSA, B);
12495   if (NestedLoopCount == 0)
12496     return StmtError();
12497 
12498   assert((CurContext->isDependentContext() || B.builtAll()) &&
12499          "omp target teams distribute parallel for loop exprs were not built");
12500 
12501   if (!CurContext->isDependentContext()) {
12502     // Finalize the clauses that need pre-built expressions for CodeGen.
12503     for (OMPClause *C : Clauses) {
12504       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12505         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12506                                      B.NumIterations, *this, CurScope,
12507                                      DSAStack))
12508           return StmtError();
12509     }
12510   }
12511 
12512   setFunctionHasBranchProtectedScope();
12513   return OMPTargetTeamsDistributeParallelForDirective::Create(
12514       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12515       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12516 }
12517 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12518 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12519     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12520     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12521   if (!AStmt)
12522     return StmtError();
12523 
12524   auto *CS = cast<CapturedStmt>(AStmt);
12525   // 1.2.2 OpenMP Language Terminology
12526   // Structured block - An executable statement with a single entry at the
12527   // top and a single exit at the bottom.
12528   // The point of exit cannot be a branch out of the structured block.
12529   // longjmp() and throw() must not violate the entry/exit criteria.
12530   CS->getCapturedDecl()->setNothrow();
12531   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12532            OMPD_target_teams_distribute_parallel_for_simd);
12533        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12534     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12535     // 1.2.2 OpenMP Language Terminology
12536     // Structured block - An executable statement with a single entry at the
12537     // top and a single exit at the bottom.
12538     // The point of exit cannot be a branch out of the structured block.
12539     // longjmp() and throw() must not violate the entry/exit criteria.
12540     CS->getCapturedDecl()->setNothrow();
12541   }
12542 
12543   OMPLoopBasedDirective::HelperExprs B;
12544   // In presence of clause 'collapse' with number of loops, it will
12545   // define the nested loops number.
12546   unsigned NestedLoopCount =
12547       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12548                       getCollapseNumberExpr(Clauses),
12549                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12550                       *DSAStack, VarsWithImplicitDSA, B);
12551   if (NestedLoopCount == 0)
12552     return StmtError();
12553 
12554   assert((CurContext->isDependentContext() || B.builtAll()) &&
12555          "omp target teams distribute parallel for simd loop exprs were not "
12556          "built");
12557 
12558   if (!CurContext->isDependentContext()) {
12559     // Finalize the clauses that need pre-built expressions for CodeGen.
12560     for (OMPClause *C : Clauses) {
12561       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12562         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12563                                      B.NumIterations, *this, CurScope,
12564                                      DSAStack))
12565           return StmtError();
12566     }
12567   }
12568 
12569   if (checkSimdlenSafelenSpecified(*this, Clauses))
12570     return StmtError();
12571 
12572   setFunctionHasBranchProtectedScope();
12573   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12574       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12575 }
12576 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12577 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12578     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12579     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12580   if (!AStmt)
12581     return StmtError();
12582 
12583   auto *CS = cast<CapturedStmt>(AStmt);
12584   // 1.2.2 OpenMP Language Terminology
12585   // Structured block - An executable statement with a single entry at the
12586   // top and a single exit at the bottom.
12587   // The point of exit cannot be a branch out of the structured block.
12588   // longjmp() and throw() must not violate the entry/exit criteria.
12589   CS->getCapturedDecl()->setNothrow();
12590   for (int ThisCaptureLevel =
12591            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12592        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12593     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12594     // 1.2.2 OpenMP Language Terminology
12595     // Structured block - An executable statement with a single entry at the
12596     // top and a single exit at the bottom.
12597     // The point of exit cannot be a branch out of the structured block.
12598     // longjmp() and throw() must not violate the entry/exit criteria.
12599     CS->getCapturedDecl()->setNothrow();
12600   }
12601 
12602   OMPLoopBasedDirective::HelperExprs B;
12603   // In presence of clause 'collapse' with number of loops, it will
12604   // define the nested loops number.
12605   unsigned NestedLoopCount = checkOpenMPLoop(
12606       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12607       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12608       VarsWithImplicitDSA, B);
12609   if (NestedLoopCount == 0)
12610     return StmtError();
12611 
12612   assert((CurContext->isDependentContext() || B.builtAll()) &&
12613          "omp target teams distribute simd loop exprs were not built");
12614 
12615   if (!CurContext->isDependentContext()) {
12616     // Finalize the clauses that need pre-built expressions for CodeGen.
12617     for (OMPClause *C : Clauses) {
12618       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12619         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12620                                      B.NumIterations, *this, CurScope,
12621                                      DSAStack))
12622           return StmtError();
12623     }
12624   }
12625 
12626   if (checkSimdlenSafelenSpecified(*this, Clauses))
12627     return StmtError();
12628 
12629   setFunctionHasBranchProtectedScope();
12630   return OMPTargetTeamsDistributeSimdDirective::Create(
12631       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12632 }
12633 
checkTransformableLoopNest(OpenMPDirectiveKind Kind,Stmt * AStmt,int NumLoops,SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> & LoopHelpers,Stmt * & Body,SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *,Decl * >,0>> & OriginalInits)12634 bool Sema::checkTransformableLoopNest(
12635     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
12636     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
12637     Stmt *&Body,
12638     SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
12639         &OriginalInits) {
12640   OriginalInits.emplace_back();
12641   bool Result = OMPLoopBasedDirective::doForAllLoops(
12642       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
12643       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
12644                                                         Stmt *CurStmt) {
12645         VarsWithInheritedDSAType TmpDSA;
12646         unsigned SingleNumLoops =
12647             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
12648                             TmpDSA, LoopHelpers[Cnt]);
12649         if (SingleNumLoops == 0)
12650           return true;
12651         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
12652         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12653           OriginalInits.back().push_back(For->getInit());
12654           Body = For->getBody();
12655         } else {
12656           assert(isa<CXXForRangeStmt>(CurStmt) &&
12657                  "Expected canonical for or range-based for loops.");
12658           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12659           OriginalInits.back().push_back(CXXFor->getBeginStmt());
12660           Body = CXXFor->getBody();
12661         }
12662         OriginalInits.emplace_back();
12663         return false;
12664       },
12665       [&OriginalInits](OMPLoopBasedDirective *Transform) {
12666         Stmt *DependentPreInits;
12667         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
12668           DependentPreInits = Dir->getPreInits();
12669         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
12670           DependentPreInits = Dir->getPreInits();
12671         else
12672           llvm_unreachable("Unhandled loop transformation");
12673         if (!DependentPreInits)
12674           return;
12675         for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup())
12676           OriginalInits.back().push_back(C);
12677       });
12678   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
12679   OriginalInits.pop_back();
12680   return Result;
12681 }
12682 
ActOnOpenMPTileDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12683 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12684                                           Stmt *AStmt, SourceLocation StartLoc,
12685                                           SourceLocation EndLoc) {
12686   auto SizesClauses =
12687       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12688   if (SizesClauses.empty()) {
12689     // A missing 'sizes' clause is already reported by the parser.
12690     return StmtError();
12691   }
12692   const OMPSizesClause *SizesClause = *SizesClauses.begin();
12693   unsigned NumLoops = SizesClause->getNumSizes();
12694 
12695   // Empty statement should only be possible if there already was an error.
12696   if (!AStmt)
12697     return StmtError();
12698 
12699   // Verify and diagnose loop nest.
12700   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12701   Stmt *Body = nullptr;
12702   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
12703       OriginalInits;
12704   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
12705                                   OriginalInits))
12706     return StmtError();
12707 
12708   // Delay tiling to when template is completely instantiated.
12709   if (CurContext->isDependentContext())
12710     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12711                                     NumLoops, AStmt, nullptr, nullptr);
12712 
12713   SmallVector<Decl *, 4> PreInits;
12714 
12715   // Create iteration variables for the generated loops.
12716   SmallVector<VarDecl *, 4> FloorIndVars;
12717   SmallVector<VarDecl *, 4> TileIndVars;
12718   FloorIndVars.resize(NumLoops);
12719   TileIndVars.resize(NumLoops);
12720   for (unsigned I = 0; I < NumLoops; ++I) {
12721     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12722 
12723     assert(LoopHelper.Counters.size() == 1 &&
12724            "Expect single-dimensional loop iteration space");
12725     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12726     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12727     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12728     QualType CntTy = IterVarRef->getType();
12729 
12730     // Iteration variable for the floor (i.e. outer) loop.
12731     {
12732       std::string FloorCntName =
12733           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12734       VarDecl *FloorCntDecl =
12735           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12736       FloorIndVars[I] = FloorCntDecl;
12737     }
12738 
12739     // Iteration variable for the tile (i.e. inner) loop.
12740     {
12741       std::string TileCntName =
12742           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12743 
12744       // Reuse the iteration variable created by checkOpenMPLoop. It is also
12745       // used by the expressions to derive the original iteration variable's
12746       // value from the logical iteration number.
12747       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12748       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12749       TileIndVars[I] = TileCntDecl;
12750     }
12751     for (auto &P : OriginalInits[I]) {
12752       if (auto *D = P.dyn_cast<Decl *>())
12753         PreInits.push_back(D);
12754       else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12755         PreInits.append(PI->decl_begin(), PI->decl_end());
12756     }
12757     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12758       PreInits.append(PI->decl_begin(), PI->decl_end());
12759     // Gather declarations for the data members used as counters.
12760     for (Expr *CounterRef : LoopHelper.Counters) {
12761       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12762       if (isa<OMPCapturedExprDecl>(CounterDecl))
12763         PreInits.push_back(CounterDecl);
12764     }
12765   }
12766 
12767   // Once the original iteration values are set, append the innermost body.
12768   Stmt *Inner = Body;
12769 
12770   // Create tile loops from the inside to the outside.
12771   for (int I = NumLoops - 1; I >= 0; --I) {
12772     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12773     Expr *NumIterations = LoopHelper.NumIterations;
12774     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12775     QualType CntTy = OrigCntVar->getType();
12776     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12777     Scope *CurScope = getCurScope();
12778 
12779     // Commonly used variables.
12780     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12781                                            OrigCntVar->getExprLoc());
12782     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12783                                             OrigCntVar->getExprLoc());
12784 
12785     // For init-statement: auto .tile.iv = .floor.iv
12786     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12787                          /*DirectInit=*/false);
12788     Decl *CounterDecl = TileIndVars[I];
12789     StmtResult InitStmt = new (Context)
12790         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12791                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12792     if (!InitStmt.isUsable())
12793       return StmtError();
12794 
12795     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12796     // NumIterations)
12797     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12798                                       BO_Add, FloorIV, DimTileSize);
12799     if (!EndOfTile.isUsable())
12800       return StmtError();
12801     ExprResult IsPartialTile =
12802         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12803                    NumIterations, EndOfTile.get());
12804     if (!IsPartialTile.isUsable())
12805       return StmtError();
12806     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12807         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12808         IsPartialTile.get(), NumIterations, EndOfTile.get());
12809     if (!MinTileAndIterSpace.isUsable())
12810       return StmtError();
12811     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12812                                      BO_LT, TileIV, MinTileAndIterSpace.get());
12813     if (!CondExpr.isUsable())
12814       return StmtError();
12815 
12816     // For incr-statement: ++.tile.iv
12817     ExprResult IncrStmt =
12818         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12819     if (!IncrStmt.isUsable())
12820       return StmtError();
12821 
12822     // Statements to set the original iteration variable's value from the
12823     // logical iteration number.
12824     // Generated for loop is:
12825     // Original_for_init;
12826     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12827     // NumIterations); ++.tile.iv) {
12828     //   Original_Body;
12829     //   Original_counter_update;
12830     // }
12831     // FIXME: If the innermost body is an loop itself, inserting these
12832     // statements stops it being recognized  as a perfectly nested loop (e.g.
12833     // for applying tiling again). If this is the case, sink the expressions
12834     // further into the inner loop.
12835     SmallVector<Stmt *, 4> BodyParts;
12836     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12837     BodyParts.push_back(Inner);
12838     Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12839                                  Inner->getEndLoc());
12840     Inner = new (Context)
12841         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12842                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12843                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12844   }
12845 
12846   // Create floor loops from the inside to the outside.
12847   for (int I = NumLoops - 1; I >= 0; --I) {
12848     auto &LoopHelper = LoopHelpers[I];
12849     Expr *NumIterations = LoopHelper.NumIterations;
12850     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12851     QualType CntTy = OrigCntVar->getType();
12852     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12853     Scope *CurScope = getCurScope();
12854 
12855     // Commonly used variables.
12856     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12857                                             OrigCntVar->getExprLoc());
12858 
12859     // For init-statement: auto .floor.iv = 0
12860     AddInitializerToDecl(
12861         FloorIndVars[I],
12862         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12863         /*DirectInit=*/false);
12864     Decl *CounterDecl = FloorIndVars[I];
12865     StmtResult InitStmt = new (Context)
12866         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12867                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12868     if (!InitStmt.isUsable())
12869       return StmtError();
12870 
12871     // For cond-expression: .floor.iv < NumIterations
12872     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12873                                      BO_LT, FloorIV, NumIterations);
12874     if (!CondExpr.isUsable())
12875       return StmtError();
12876 
12877     // For incr-statement: .floor.iv += DimTileSize
12878     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12879                                      BO_AddAssign, FloorIV, DimTileSize);
12880     if (!IncrStmt.isUsable())
12881       return StmtError();
12882 
12883     Inner = new (Context)
12884         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12885                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12886                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12887   }
12888 
12889   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12890                                   AStmt, Inner,
12891                                   buildPreInits(Context, PreInits));
12892 }
12893 
ActOnOpenMPUnrollDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12894 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
12895                                             Stmt *AStmt,
12896                                             SourceLocation StartLoc,
12897                                             SourceLocation EndLoc) {
12898   // Empty statement should only be possible if there already was an error.
12899   if (!AStmt)
12900     return StmtError();
12901 
12902   if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
12903     return StmtError();
12904 
12905   const OMPFullClause *FullClause =
12906       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
12907   const OMPPartialClause *PartialClause =
12908       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
12909   assert(!(FullClause && PartialClause) &&
12910          "mutual exclusivity must have been checked before");
12911 
12912   constexpr unsigned NumLoops = 1;
12913   Stmt *Body = nullptr;
12914   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
12915       NumLoops);
12916   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
12917       OriginalInits;
12918   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
12919                                   Body, OriginalInits))
12920     return StmtError();
12921 
12922   unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
12923 
12924   // Delay unrolling to when template is completely instantiated.
12925   if (CurContext->isDependentContext())
12926     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12927                                       NumGeneratedLoops, nullptr, nullptr);
12928 
12929   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
12930 
12931   if (FullClause) {
12932     if (!VerifyPositiveIntegerConstantInClause(
12933              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
12934              /*SuppressExprDigs=*/true)
12935              .isUsable()) {
12936       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
12937       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
12938           << "#pragma omp unroll full";
12939       return StmtError();
12940     }
12941   }
12942 
12943   // The generated loop may only be passed to other loop-associated directive
12944   // when a partial clause is specified. Without the requirement it is
12945   // sufficient to generate loop unroll metadata at code-generation.
12946   if (NumGeneratedLoops == 0)
12947     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12948                                       NumGeneratedLoops, nullptr, nullptr);
12949 
12950   // Otherwise, we need to provide a de-sugared/transformed AST that can be
12951   // associated with another loop directive.
12952   //
12953   // The canonical loop analysis return by checkTransformableLoopNest assumes
12954   // the following structure to be the same loop without transformations or
12955   // directives applied: \code OriginalInits; LoopHelper.PreInits;
12956   // LoopHelper.Counters;
12957   // for (; IV < LoopHelper.NumIterations; ++IV) {
12958   //   LoopHelper.Updates;
12959   //   Body;
12960   // }
12961   // \endcode
12962   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
12963   // and referenced by LoopHelper.IterationVarRef.
12964   //
12965   // The unrolling directive transforms this into the following loop:
12966   // \code
12967   // OriginalInits;         \
12968   // LoopHelper.PreInits;    > NewPreInits
12969   // LoopHelper.Counters;   /
12970   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
12971   //   #pragma clang loop unroll_count(Factor)
12972   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
12973   //   {
12974   //     LoopHelper.Updates;
12975   //     Body;
12976   //   }
12977   // }
12978   // \endcode
12979   // where UIV is a new logical iteration counter. IV must be the same VarDecl
12980   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
12981   // references it. If the partially unrolled loop is associated with another
12982   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
12983   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
12984   // OpenMP canonical loop. The inner loop is not an associable canonical loop
12985   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
12986   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
12987   // property of the OMPLoopBasedDirective instead of statements in
12988   // CompoundStatement. This is to allow the loop to become a non-outermost loop
12989   // of a canonical loop nest where these PreInits are emitted before the
12990   // outermost directive.
12991 
12992   // Determine the PreInit declarations.
12993   SmallVector<Decl *, 4> PreInits;
12994   assert(OriginalInits.size() == 1 &&
12995          "Expecting a single-dimensional loop iteration space");
12996   for (auto &P : OriginalInits[0]) {
12997     if (auto *D = P.dyn_cast<Decl *>())
12998       PreInits.push_back(D);
12999     else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
13000       PreInits.append(PI->decl_begin(), PI->decl_end());
13001   }
13002   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
13003     PreInits.append(PI->decl_begin(), PI->decl_end());
13004   // Gather declarations for the data members used as counters.
13005   for (Expr *CounterRef : LoopHelper.Counters) {
13006     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
13007     if (isa<OMPCapturedExprDecl>(CounterDecl))
13008       PreInits.push_back(CounterDecl);
13009   }
13010 
13011   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
13012   QualType IVTy = IterationVarRef->getType();
13013   assert(LoopHelper.Counters.size() == 1 &&
13014          "Expecting a single-dimensional loop iteration space");
13015   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
13016 
13017   // Determine the unroll factor.
13018   uint64_t Factor;
13019   SourceLocation FactorLoc;
13020   if (Expr *FactorVal = PartialClause->getFactor()) {
13021     Factor =
13022         FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
13023     FactorLoc = FactorVal->getExprLoc();
13024   } else {
13025     // TODO: Use a better profitability model.
13026     Factor = 2;
13027   }
13028   assert(Factor > 0 && "Expected positive unroll factor");
13029   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
13030     return IntegerLiteral::Create(
13031         Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
13032         FactorLoc);
13033   };
13034 
13035   // Iteration variable SourceLocations.
13036   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
13037   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
13038   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
13039 
13040   // Internal variable names.
13041   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
13042   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
13043   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
13044   std::string InnerTripCountName =
13045       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
13046 
13047   // Create the iteration variable for the unrolled loop.
13048   VarDecl *OuterIVDecl =
13049       buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
13050   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
13051     return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
13052   };
13053 
13054   // Iteration variable for the inner loop: Reuse the iteration variable created
13055   // by checkOpenMPLoop.
13056   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
13057   InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
13058   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
13059     return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
13060   };
13061 
13062   // Make a copy of the NumIterations expression for each use: By the AST
13063   // constraints, every expression object in a DeclContext must be unique.
13064   CaptureVars CopyTransformer(*this);
13065   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
13066     return AssertSuccess(
13067         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
13068   };
13069 
13070   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
13071   ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
13072   AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
13073   StmtResult InnerInit = new (Context)
13074       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13075   if (!InnerInit.isUsable())
13076     return StmtError();
13077 
13078   // Inner For cond-expression:
13079   // \code
13080   //   .unroll_inner.iv < .unrolled.iv + Factor &&
13081   //   .unroll_inner.iv < NumIterations
13082   // \endcode
13083   // This conjunction of two conditions allows ScalarEvolution to derive the
13084   // maximum trip count of the inner loop.
13085   ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13086                                     BO_Add, MakeOuterRef(), MakeFactorExpr());
13087   if (!EndOfTile.isUsable())
13088     return StmtError();
13089   ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13090                                      BO_LE, MakeInnerRef(), EndOfTile.get());
13091   if (!InnerCond1.isUsable())
13092     return StmtError();
13093   ExprResult InnerCond2 =
13094       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
13095                  MakeNumIterations());
13096   if (!InnerCond2.isUsable())
13097     return StmtError();
13098   ExprResult InnerCond =
13099       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
13100                  InnerCond1.get(), InnerCond2.get());
13101   if (!InnerCond.isUsable())
13102     return StmtError();
13103 
13104   // Inner For incr-statement: ++.unroll_inner.iv
13105   ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
13106                                       UO_PreInc, MakeInnerRef());
13107   if (!InnerIncr.isUsable())
13108     return StmtError();
13109 
13110   // Inner For statement.
13111   SmallVector<Stmt *> InnerBodyStmts;
13112   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
13113   InnerBodyStmts.push_back(Body);
13114   CompoundStmt *InnerBody = CompoundStmt::Create(
13115       Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
13116   ForStmt *InnerFor = new (Context)
13117       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
13118               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
13119               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13120 
13121   // Unroll metadata for the inner loop.
13122   // This needs to take into account the remainder portion of the unrolled loop,
13123   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
13124   // supports multiple loop exits. Instead, unroll using a factor equivalent to
13125   // the maximum trip count, which will also generate a remainder loop. Just
13126   // `unroll(enable)` (which could have been useful if the user has not
13127   // specified a concrete factor; even though the outer loop cannot be
13128   // influenced anymore, would avoid more code bloat than necessary) will refuse
13129   // the loop because "Won't unroll; remainder loop could not be generated when
13130   // assuming runtime trip count". Even if it did work, it must not choose a
13131   // larger unroll factor than the maximum loop length, or it would always just
13132   // execute the remainder loop.
13133   LoopHintAttr *UnrollHintAttr =
13134       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
13135                                    LoopHintAttr::Numeric, MakeFactorExpr());
13136   AttributedStmt *InnerUnrolled =
13137       AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
13138 
13139   // Outer For init-statement: auto .unrolled.iv = 0
13140   AddInitializerToDecl(
13141       OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
13142       /*DirectInit=*/false);
13143   StmtResult OuterInit = new (Context)
13144       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13145   if (!OuterInit.isUsable())
13146     return StmtError();
13147 
13148   // Outer For cond-expression: .unrolled.iv < NumIterations
13149   ExprResult OuterConde =
13150       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
13151                  MakeNumIterations());
13152   if (!OuterConde.isUsable())
13153     return StmtError();
13154 
13155   // Outer For incr-statement: .unrolled.iv += Factor
13156   ExprResult OuterIncr =
13157       BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
13158                  MakeOuterRef(), MakeFactorExpr());
13159   if (!OuterIncr.isUsable())
13160     return StmtError();
13161 
13162   // Outer For statement.
13163   ForStmt *OuterFor = new (Context)
13164       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
13165               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
13166               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13167 
13168   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
13169                                     NumGeneratedLoops, OuterFor,
13170                                     buildPreInits(Context, PreInits));
13171 }
13172 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13173 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
13174                                              SourceLocation StartLoc,
13175                                              SourceLocation LParenLoc,
13176                                              SourceLocation EndLoc) {
13177   OMPClause *Res = nullptr;
13178   switch (Kind) {
13179   case OMPC_final:
13180     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
13181     break;
13182   case OMPC_num_threads:
13183     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
13184     break;
13185   case OMPC_safelen:
13186     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
13187     break;
13188   case OMPC_simdlen:
13189     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
13190     break;
13191   case OMPC_allocator:
13192     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
13193     break;
13194   case OMPC_collapse:
13195     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
13196     break;
13197   case OMPC_ordered:
13198     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
13199     break;
13200   case OMPC_num_teams:
13201     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
13202     break;
13203   case OMPC_thread_limit:
13204     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
13205     break;
13206   case OMPC_priority:
13207     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
13208     break;
13209   case OMPC_grainsize:
13210     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
13211     break;
13212   case OMPC_num_tasks:
13213     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
13214     break;
13215   case OMPC_hint:
13216     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
13217     break;
13218   case OMPC_depobj:
13219     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
13220     break;
13221   case OMPC_detach:
13222     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
13223     break;
13224   case OMPC_novariants:
13225     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
13226     break;
13227   case OMPC_nocontext:
13228     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
13229     break;
13230   case OMPC_filter:
13231     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
13232     break;
13233   case OMPC_partial:
13234     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
13235     break;
13236   case OMPC_device:
13237   case OMPC_if:
13238   case OMPC_default:
13239   case OMPC_proc_bind:
13240   case OMPC_schedule:
13241   case OMPC_private:
13242   case OMPC_firstprivate:
13243   case OMPC_lastprivate:
13244   case OMPC_shared:
13245   case OMPC_reduction:
13246   case OMPC_task_reduction:
13247   case OMPC_in_reduction:
13248   case OMPC_linear:
13249   case OMPC_aligned:
13250   case OMPC_copyin:
13251   case OMPC_copyprivate:
13252   case OMPC_nowait:
13253   case OMPC_untied:
13254   case OMPC_mergeable:
13255   case OMPC_threadprivate:
13256   case OMPC_sizes:
13257   case OMPC_allocate:
13258   case OMPC_flush:
13259   case OMPC_read:
13260   case OMPC_write:
13261   case OMPC_update:
13262   case OMPC_capture:
13263   case OMPC_seq_cst:
13264   case OMPC_acq_rel:
13265   case OMPC_acquire:
13266   case OMPC_release:
13267   case OMPC_relaxed:
13268   case OMPC_depend:
13269   case OMPC_threads:
13270   case OMPC_simd:
13271   case OMPC_map:
13272   case OMPC_nogroup:
13273   case OMPC_dist_schedule:
13274   case OMPC_defaultmap:
13275   case OMPC_unknown:
13276   case OMPC_uniform:
13277   case OMPC_to:
13278   case OMPC_from:
13279   case OMPC_use_device_ptr:
13280   case OMPC_use_device_addr:
13281   case OMPC_is_device_ptr:
13282   case OMPC_unified_address:
13283   case OMPC_unified_shared_memory:
13284   case OMPC_reverse_offload:
13285   case OMPC_dynamic_allocators:
13286   case OMPC_atomic_default_mem_order:
13287   case OMPC_device_type:
13288   case OMPC_match:
13289   case OMPC_nontemporal:
13290   case OMPC_order:
13291   case OMPC_destroy:
13292   case OMPC_inclusive:
13293   case OMPC_exclusive:
13294   case OMPC_uses_allocators:
13295   case OMPC_affinity:
13296   case OMPC_when:
13297   default:
13298     llvm_unreachable("Clause is not allowed.");
13299   }
13300   return Res;
13301 }
13302 
13303 // An OpenMP directive such as 'target parallel' has two captured regions:
13304 // for the 'target' and 'parallel' respectively.  This function returns
13305 // the region in which to capture expressions associated with a clause.
13306 // A return value of OMPD_unknown signifies that the expression should not
13307 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)13308 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
13309     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
13310     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
13311   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13312   switch (CKind) {
13313   case OMPC_if:
13314     switch (DKind) {
13315     case OMPD_target_parallel_for_simd:
13316       if (OpenMPVersion >= 50 &&
13317           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13318         CaptureRegion = OMPD_parallel;
13319         break;
13320       }
13321       LLVM_FALLTHROUGH;
13322     case OMPD_target_parallel:
13323     case OMPD_target_parallel_for:
13324       // If this clause applies to the nested 'parallel' region, capture within
13325       // the 'target' region, otherwise do not capture.
13326       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13327         CaptureRegion = OMPD_target;
13328       break;
13329     case OMPD_target_teams_distribute_parallel_for_simd:
13330       if (OpenMPVersion >= 50 &&
13331           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13332         CaptureRegion = OMPD_parallel;
13333         break;
13334       }
13335       LLVM_FALLTHROUGH;
13336     case OMPD_target_teams_distribute_parallel_for:
13337       // If this clause applies to the nested 'parallel' region, capture within
13338       // the 'teams' region, otherwise do not capture.
13339       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13340         CaptureRegion = OMPD_teams;
13341       break;
13342     case OMPD_teams_distribute_parallel_for_simd:
13343       if (OpenMPVersion >= 50 &&
13344           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13345         CaptureRegion = OMPD_parallel;
13346         break;
13347       }
13348       LLVM_FALLTHROUGH;
13349     case OMPD_teams_distribute_parallel_for:
13350       CaptureRegion = OMPD_teams;
13351       break;
13352     case OMPD_target_update:
13353     case OMPD_target_enter_data:
13354     case OMPD_target_exit_data:
13355       CaptureRegion = OMPD_task;
13356       break;
13357     case OMPD_parallel_master_taskloop:
13358       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
13359         CaptureRegion = OMPD_parallel;
13360       break;
13361     case OMPD_parallel_master_taskloop_simd:
13362       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
13363           NameModifier == OMPD_taskloop) {
13364         CaptureRegion = OMPD_parallel;
13365         break;
13366       }
13367       if (OpenMPVersion <= 45)
13368         break;
13369       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13370         CaptureRegion = OMPD_taskloop;
13371       break;
13372     case OMPD_parallel_for_simd:
13373       if (OpenMPVersion <= 45)
13374         break;
13375       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13376         CaptureRegion = OMPD_parallel;
13377       break;
13378     case OMPD_taskloop_simd:
13379     case OMPD_master_taskloop_simd:
13380       if (OpenMPVersion <= 45)
13381         break;
13382       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13383         CaptureRegion = OMPD_taskloop;
13384       break;
13385     case OMPD_distribute_parallel_for_simd:
13386       if (OpenMPVersion <= 45)
13387         break;
13388       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13389         CaptureRegion = OMPD_parallel;
13390       break;
13391     case OMPD_target_simd:
13392       if (OpenMPVersion >= 50 &&
13393           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13394         CaptureRegion = OMPD_target;
13395       break;
13396     case OMPD_teams_distribute_simd:
13397     case OMPD_target_teams_distribute_simd:
13398       if (OpenMPVersion >= 50 &&
13399           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13400         CaptureRegion = OMPD_teams;
13401       break;
13402     case OMPD_cancel:
13403     case OMPD_parallel:
13404     case OMPD_parallel_master:
13405     case OMPD_parallel_sections:
13406     case OMPD_parallel_for:
13407     case OMPD_target:
13408     case OMPD_target_teams:
13409     case OMPD_target_teams_distribute:
13410     case OMPD_distribute_parallel_for:
13411     case OMPD_task:
13412     case OMPD_taskloop:
13413     case OMPD_master_taskloop:
13414     case OMPD_target_data:
13415     case OMPD_simd:
13416     case OMPD_for_simd:
13417     case OMPD_distribute_simd:
13418       // Do not capture if-clause expressions.
13419       break;
13420     case OMPD_threadprivate:
13421     case OMPD_allocate:
13422     case OMPD_taskyield:
13423     case OMPD_barrier:
13424     case OMPD_taskwait:
13425     case OMPD_cancellation_point:
13426     case OMPD_flush:
13427     case OMPD_depobj:
13428     case OMPD_scan:
13429     case OMPD_declare_reduction:
13430     case OMPD_declare_mapper:
13431     case OMPD_declare_simd:
13432     case OMPD_declare_variant:
13433     case OMPD_begin_declare_variant:
13434     case OMPD_end_declare_variant:
13435     case OMPD_declare_target:
13436     case OMPD_end_declare_target:
13437     case OMPD_teams:
13438     case OMPD_tile:
13439     case OMPD_unroll:
13440     case OMPD_for:
13441     case OMPD_sections:
13442     case OMPD_section:
13443     case OMPD_single:
13444     case OMPD_master:
13445     case OMPD_masked:
13446     case OMPD_critical:
13447     case OMPD_taskgroup:
13448     case OMPD_distribute:
13449     case OMPD_ordered:
13450     case OMPD_atomic:
13451     case OMPD_teams_distribute:
13452     case OMPD_requires:
13453     case OMPD_metadirective:
13454       llvm_unreachable("Unexpected OpenMP directive with if-clause");
13455     case OMPD_unknown:
13456     default:
13457       llvm_unreachable("Unknown OpenMP directive");
13458     }
13459     break;
13460   case OMPC_num_threads:
13461     switch (DKind) {
13462     case OMPD_target_parallel:
13463     case OMPD_target_parallel_for:
13464     case OMPD_target_parallel_for_simd:
13465       CaptureRegion = OMPD_target;
13466       break;
13467     case OMPD_teams_distribute_parallel_for:
13468     case OMPD_teams_distribute_parallel_for_simd:
13469     case OMPD_target_teams_distribute_parallel_for:
13470     case OMPD_target_teams_distribute_parallel_for_simd:
13471       CaptureRegion = OMPD_teams;
13472       break;
13473     case OMPD_parallel:
13474     case OMPD_parallel_master:
13475     case OMPD_parallel_sections:
13476     case OMPD_parallel_for:
13477     case OMPD_parallel_for_simd:
13478     case OMPD_distribute_parallel_for:
13479     case OMPD_distribute_parallel_for_simd:
13480     case OMPD_parallel_master_taskloop:
13481     case OMPD_parallel_master_taskloop_simd:
13482       // Do not capture num_threads-clause expressions.
13483       break;
13484     case OMPD_target_data:
13485     case OMPD_target_enter_data:
13486     case OMPD_target_exit_data:
13487     case OMPD_target_update:
13488     case OMPD_target:
13489     case OMPD_target_simd:
13490     case OMPD_target_teams:
13491     case OMPD_target_teams_distribute:
13492     case OMPD_target_teams_distribute_simd:
13493     case OMPD_cancel:
13494     case OMPD_task:
13495     case OMPD_taskloop:
13496     case OMPD_taskloop_simd:
13497     case OMPD_master_taskloop:
13498     case OMPD_master_taskloop_simd:
13499     case OMPD_threadprivate:
13500     case OMPD_allocate:
13501     case OMPD_taskyield:
13502     case OMPD_barrier:
13503     case OMPD_taskwait:
13504     case OMPD_cancellation_point:
13505     case OMPD_flush:
13506     case OMPD_depobj:
13507     case OMPD_scan:
13508     case OMPD_declare_reduction:
13509     case OMPD_declare_mapper:
13510     case OMPD_declare_simd:
13511     case OMPD_declare_variant:
13512     case OMPD_begin_declare_variant:
13513     case OMPD_end_declare_variant:
13514     case OMPD_declare_target:
13515     case OMPD_end_declare_target:
13516     case OMPD_teams:
13517     case OMPD_simd:
13518     case OMPD_tile:
13519     case OMPD_unroll:
13520     case OMPD_for:
13521     case OMPD_for_simd:
13522     case OMPD_sections:
13523     case OMPD_section:
13524     case OMPD_single:
13525     case OMPD_master:
13526     case OMPD_masked:
13527     case OMPD_critical:
13528     case OMPD_taskgroup:
13529     case OMPD_distribute:
13530     case OMPD_ordered:
13531     case OMPD_atomic:
13532     case OMPD_distribute_simd:
13533     case OMPD_teams_distribute:
13534     case OMPD_teams_distribute_simd:
13535     case OMPD_requires:
13536     case OMPD_metadirective:
13537       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
13538     case OMPD_unknown:
13539     default:
13540       llvm_unreachable("Unknown OpenMP directive");
13541     }
13542     break;
13543   case OMPC_num_teams:
13544     switch (DKind) {
13545     case OMPD_target_teams:
13546     case OMPD_target_teams_distribute:
13547     case OMPD_target_teams_distribute_simd:
13548     case OMPD_target_teams_distribute_parallel_for:
13549     case OMPD_target_teams_distribute_parallel_for_simd:
13550       CaptureRegion = OMPD_target;
13551       break;
13552     case OMPD_teams_distribute_parallel_for:
13553     case OMPD_teams_distribute_parallel_for_simd:
13554     case OMPD_teams:
13555     case OMPD_teams_distribute:
13556     case OMPD_teams_distribute_simd:
13557       // Do not capture num_teams-clause expressions.
13558       break;
13559     case OMPD_distribute_parallel_for:
13560     case OMPD_distribute_parallel_for_simd:
13561     case OMPD_task:
13562     case OMPD_taskloop:
13563     case OMPD_taskloop_simd:
13564     case OMPD_master_taskloop:
13565     case OMPD_master_taskloop_simd:
13566     case OMPD_parallel_master_taskloop:
13567     case OMPD_parallel_master_taskloop_simd:
13568     case OMPD_target_data:
13569     case OMPD_target_enter_data:
13570     case OMPD_target_exit_data:
13571     case OMPD_target_update:
13572     case OMPD_cancel:
13573     case OMPD_parallel:
13574     case OMPD_parallel_master:
13575     case OMPD_parallel_sections:
13576     case OMPD_parallel_for:
13577     case OMPD_parallel_for_simd:
13578     case OMPD_target:
13579     case OMPD_target_simd:
13580     case OMPD_target_parallel:
13581     case OMPD_target_parallel_for:
13582     case OMPD_target_parallel_for_simd:
13583     case OMPD_threadprivate:
13584     case OMPD_allocate:
13585     case OMPD_taskyield:
13586     case OMPD_barrier:
13587     case OMPD_taskwait:
13588     case OMPD_cancellation_point:
13589     case OMPD_flush:
13590     case OMPD_depobj:
13591     case OMPD_scan:
13592     case OMPD_declare_reduction:
13593     case OMPD_declare_mapper:
13594     case OMPD_declare_simd:
13595     case OMPD_declare_variant:
13596     case OMPD_begin_declare_variant:
13597     case OMPD_end_declare_variant:
13598     case OMPD_declare_target:
13599     case OMPD_end_declare_target:
13600     case OMPD_simd:
13601     case OMPD_tile:
13602     case OMPD_unroll:
13603     case OMPD_for:
13604     case OMPD_for_simd:
13605     case OMPD_sections:
13606     case OMPD_section:
13607     case OMPD_single:
13608     case OMPD_master:
13609     case OMPD_masked:
13610     case OMPD_critical:
13611     case OMPD_taskgroup:
13612     case OMPD_distribute:
13613     case OMPD_ordered:
13614     case OMPD_atomic:
13615     case OMPD_distribute_simd:
13616     case OMPD_requires:
13617     case OMPD_metadirective:
13618       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
13619     case OMPD_unknown:
13620     default:
13621       llvm_unreachable("Unknown OpenMP directive");
13622     }
13623     break;
13624   case OMPC_thread_limit:
13625     switch (DKind) {
13626     case OMPD_target_teams:
13627     case OMPD_target_teams_distribute:
13628     case OMPD_target_teams_distribute_simd:
13629     case OMPD_target_teams_distribute_parallel_for:
13630     case OMPD_target_teams_distribute_parallel_for_simd:
13631       CaptureRegion = OMPD_target;
13632       break;
13633     case OMPD_teams_distribute_parallel_for:
13634     case OMPD_teams_distribute_parallel_for_simd:
13635     case OMPD_teams:
13636     case OMPD_teams_distribute:
13637     case OMPD_teams_distribute_simd:
13638       // Do not capture thread_limit-clause expressions.
13639       break;
13640     case OMPD_distribute_parallel_for:
13641     case OMPD_distribute_parallel_for_simd:
13642     case OMPD_task:
13643     case OMPD_taskloop:
13644     case OMPD_taskloop_simd:
13645     case OMPD_master_taskloop:
13646     case OMPD_master_taskloop_simd:
13647     case OMPD_parallel_master_taskloop:
13648     case OMPD_parallel_master_taskloop_simd:
13649     case OMPD_target_data:
13650     case OMPD_target_enter_data:
13651     case OMPD_target_exit_data:
13652     case OMPD_target_update:
13653     case OMPD_cancel:
13654     case OMPD_parallel:
13655     case OMPD_parallel_master:
13656     case OMPD_parallel_sections:
13657     case OMPD_parallel_for:
13658     case OMPD_parallel_for_simd:
13659     case OMPD_target:
13660     case OMPD_target_simd:
13661     case OMPD_target_parallel:
13662     case OMPD_target_parallel_for:
13663     case OMPD_target_parallel_for_simd:
13664     case OMPD_threadprivate:
13665     case OMPD_allocate:
13666     case OMPD_taskyield:
13667     case OMPD_barrier:
13668     case OMPD_taskwait:
13669     case OMPD_cancellation_point:
13670     case OMPD_flush:
13671     case OMPD_depobj:
13672     case OMPD_scan:
13673     case OMPD_declare_reduction:
13674     case OMPD_declare_mapper:
13675     case OMPD_declare_simd:
13676     case OMPD_declare_variant:
13677     case OMPD_begin_declare_variant:
13678     case OMPD_end_declare_variant:
13679     case OMPD_declare_target:
13680     case OMPD_end_declare_target:
13681     case OMPD_simd:
13682     case OMPD_tile:
13683     case OMPD_unroll:
13684     case OMPD_for:
13685     case OMPD_for_simd:
13686     case OMPD_sections:
13687     case OMPD_section:
13688     case OMPD_single:
13689     case OMPD_master:
13690     case OMPD_masked:
13691     case OMPD_critical:
13692     case OMPD_taskgroup:
13693     case OMPD_distribute:
13694     case OMPD_ordered:
13695     case OMPD_atomic:
13696     case OMPD_distribute_simd:
13697     case OMPD_requires:
13698     case OMPD_metadirective:
13699       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
13700     case OMPD_unknown:
13701     default:
13702       llvm_unreachable("Unknown OpenMP directive");
13703     }
13704     break;
13705   case OMPC_schedule:
13706     switch (DKind) {
13707     case OMPD_parallel_for:
13708     case OMPD_parallel_for_simd:
13709     case OMPD_distribute_parallel_for:
13710     case OMPD_distribute_parallel_for_simd:
13711     case OMPD_teams_distribute_parallel_for:
13712     case OMPD_teams_distribute_parallel_for_simd:
13713     case OMPD_target_parallel_for:
13714     case OMPD_target_parallel_for_simd:
13715     case OMPD_target_teams_distribute_parallel_for:
13716     case OMPD_target_teams_distribute_parallel_for_simd:
13717       CaptureRegion = OMPD_parallel;
13718       break;
13719     case OMPD_for:
13720     case OMPD_for_simd:
13721       // Do not capture schedule-clause expressions.
13722       break;
13723     case OMPD_task:
13724     case OMPD_taskloop:
13725     case OMPD_taskloop_simd:
13726     case OMPD_master_taskloop:
13727     case OMPD_master_taskloop_simd:
13728     case OMPD_parallel_master_taskloop:
13729     case OMPD_parallel_master_taskloop_simd:
13730     case OMPD_target_data:
13731     case OMPD_target_enter_data:
13732     case OMPD_target_exit_data:
13733     case OMPD_target_update:
13734     case OMPD_teams:
13735     case OMPD_teams_distribute:
13736     case OMPD_teams_distribute_simd:
13737     case OMPD_target_teams_distribute:
13738     case OMPD_target_teams_distribute_simd:
13739     case OMPD_target:
13740     case OMPD_target_simd:
13741     case OMPD_target_parallel:
13742     case OMPD_cancel:
13743     case OMPD_parallel:
13744     case OMPD_parallel_master:
13745     case OMPD_parallel_sections:
13746     case OMPD_threadprivate:
13747     case OMPD_allocate:
13748     case OMPD_taskyield:
13749     case OMPD_barrier:
13750     case OMPD_taskwait:
13751     case OMPD_cancellation_point:
13752     case OMPD_flush:
13753     case OMPD_depobj:
13754     case OMPD_scan:
13755     case OMPD_declare_reduction:
13756     case OMPD_declare_mapper:
13757     case OMPD_declare_simd:
13758     case OMPD_declare_variant:
13759     case OMPD_begin_declare_variant:
13760     case OMPD_end_declare_variant:
13761     case OMPD_declare_target:
13762     case OMPD_end_declare_target:
13763     case OMPD_simd:
13764     case OMPD_tile:
13765     case OMPD_unroll:
13766     case OMPD_sections:
13767     case OMPD_section:
13768     case OMPD_single:
13769     case OMPD_master:
13770     case OMPD_masked:
13771     case OMPD_critical:
13772     case OMPD_taskgroup:
13773     case OMPD_distribute:
13774     case OMPD_ordered:
13775     case OMPD_atomic:
13776     case OMPD_distribute_simd:
13777     case OMPD_target_teams:
13778     case OMPD_requires:
13779     case OMPD_metadirective:
13780       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
13781     case OMPD_unknown:
13782     default:
13783       llvm_unreachable("Unknown OpenMP directive");
13784     }
13785     break;
13786   case OMPC_dist_schedule:
13787     switch (DKind) {
13788     case OMPD_teams_distribute_parallel_for:
13789     case OMPD_teams_distribute_parallel_for_simd:
13790     case OMPD_teams_distribute:
13791     case OMPD_teams_distribute_simd:
13792     case OMPD_target_teams_distribute_parallel_for:
13793     case OMPD_target_teams_distribute_parallel_for_simd:
13794     case OMPD_target_teams_distribute:
13795     case OMPD_target_teams_distribute_simd:
13796       CaptureRegion = OMPD_teams;
13797       break;
13798     case OMPD_distribute_parallel_for:
13799     case OMPD_distribute_parallel_for_simd:
13800     case OMPD_distribute:
13801     case OMPD_distribute_simd:
13802       // Do not capture dist_schedule-clause expressions.
13803       break;
13804     case OMPD_parallel_for:
13805     case OMPD_parallel_for_simd:
13806     case OMPD_target_parallel_for_simd:
13807     case OMPD_target_parallel_for:
13808     case OMPD_task:
13809     case OMPD_taskloop:
13810     case OMPD_taskloop_simd:
13811     case OMPD_master_taskloop:
13812     case OMPD_master_taskloop_simd:
13813     case OMPD_parallel_master_taskloop:
13814     case OMPD_parallel_master_taskloop_simd:
13815     case OMPD_target_data:
13816     case OMPD_target_enter_data:
13817     case OMPD_target_exit_data:
13818     case OMPD_target_update:
13819     case OMPD_teams:
13820     case OMPD_target:
13821     case OMPD_target_simd:
13822     case OMPD_target_parallel:
13823     case OMPD_cancel:
13824     case OMPD_parallel:
13825     case OMPD_parallel_master:
13826     case OMPD_parallel_sections:
13827     case OMPD_threadprivate:
13828     case OMPD_allocate:
13829     case OMPD_taskyield:
13830     case OMPD_barrier:
13831     case OMPD_taskwait:
13832     case OMPD_cancellation_point:
13833     case OMPD_flush:
13834     case OMPD_depobj:
13835     case OMPD_scan:
13836     case OMPD_declare_reduction:
13837     case OMPD_declare_mapper:
13838     case OMPD_declare_simd:
13839     case OMPD_declare_variant:
13840     case OMPD_begin_declare_variant:
13841     case OMPD_end_declare_variant:
13842     case OMPD_declare_target:
13843     case OMPD_end_declare_target:
13844     case OMPD_simd:
13845     case OMPD_tile:
13846     case OMPD_unroll:
13847     case OMPD_for:
13848     case OMPD_for_simd:
13849     case OMPD_sections:
13850     case OMPD_section:
13851     case OMPD_single:
13852     case OMPD_master:
13853     case OMPD_masked:
13854     case OMPD_critical:
13855     case OMPD_taskgroup:
13856     case OMPD_ordered:
13857     case OMPD_atomic:
13858     case OMPD_target_teams:
13859     case OMPD_requires:
13860     case OMPD_metadirective:
13861       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
13862     case OMPD_unknown:
13863     default:
13864       llvm_unreachable("Unknown OpenMP directive");
13865     }
13866     break;
13867   case OMPC_device:
13868     switch (DKind) {
13869     case OMPD_target_update:
13870     case OMPD_target_enter_data:
13871     case OMPD_target_exit_data:
13872     case OMPD_target:
13873     case OMPD_target_simd:
13874     case OMPD_target_teams:
13875     case OMPD_target_parallel:
13876     case OMPD_target_teams_distribute:
13877     case OMPD_target_teams_distribute_simd:
13878     case OMPD_target_parallel_for:
13879     case OMPD_target_parallel_for_simd:
13880     case OMPD_target_teams_distribute_parallel_for:
13881     case OMPD_target_teams_distribute_parallel_for_simd:
13882     case OMPD_dispatch:
13883       CaptureRegion = OMPD_task;
13884       break;
13885     case OMPD_target_data:
13886     case OMPD_interop:
13887       // Do not capture device-clause expressions.
13888       break;
13889     case OMPD_teams_distribute_parallel_for:
13890     case OMPD_teams_distribute_parallel_for_simd:
13891     case OMPD_teams:
13892     case OMPD_teams_distribute:
13893     case OMPD_teams_distribute_simd:
13894     case OMPD_distribute_parallel_for:
13895     case OMPD_distribute_parallel_for_simd:
13896     case OMPD_task:
13897     case OMPD_taskloop:
13898     case OMPD_taskloop_simd:
13899     case OMPD_master_taskloop:
13900     case OMPD_master_taskloop_simd:
13901     case OMPD_parallel_master_taskloop:
13902     case OMPD_parallel_master_taskloop_simd:
13903     case OMPD_cancel:
13904     case OMPD_parallel:
13905     case OMPD_parallel_master:
13906     case OMPD_parallel_sections:
13907     case OMPD_parallel_for:
13908     case OMPD_parallel_for_simd:
13909     case OMPD_threadprivate:
13910     case OMPD_allocate:
13911     case OMPD_taskyield:
13912     case OMPD_barrier:
13913     case OMPD_taskwait:
13914     case OMPD_cancellation_point:
13915     case OMPD_flush:
13916     case OMPD_depobj:
13917     case OMPD_scan:
13918     case OMPD_declare_reduction:
13919     case OMPD_declare_mapper:
13920     case OMPD_declare_simd:
13921     case OMPD_declare_variant:
13922     case OMPD_begin_declare_variant:
13923     case OMPD_end_declare_variant:
13924     case OMPD_declare_target:
13925     case OMPD_end_declare_target:
13926     case OMPD_simd:
13927     case OMPD_tile:
13928     case OMPD_unroll:
13929     case OMPD_for:
13930     case OMPD_for_simd:
13931     case OMPD_sections:
13932     case OMPD_section:
13933     case OMPD_single:
13934     case OMPD_master:
13935     case OMPD_masked:
13936     case OMPD_critical:
13937     case OMPD_taskgroup:
13938     case OMPD_distribute:
13939     case OMPD_ordered:
13940     case OMPD_atomic:
13941     case OMPD_distribute_simd:
13942     case OMPD_requires:
13943     case OMPD_metadirective:
13944       llvm_unreachable("Unexpected OpenMP directive with device-clause");
13945     case OMPD_unknown:
13946     default:
13947       llvm_unreachable("Unknown OpenMP directive");
13948     }
13949     break;
13950   case OMPC_grainsize:
13951   case OMPC_num_tasks:
13952   case OMPC_final:
13953   case OMPC_priority:
13954     switch (DKind) {
13955     case OMPD_task:
13956     case OMPD_taskloop:
13957     case OMPD_taskloop_simd:
13958     case OMPD_master_taskloop:
13959     case OMPD_master_taskloop_simd:
13960       break;
13961     case OMPD_parallel_master_taskloop:
13962     case OMPD_parallel_master_taskloop_simd:
13963       CaptureRegion = OMPD_parallel;
13964       break;
13965     case OMPD_target_update:
13966     case OMPD_target_enter_data:
13967     case OMPD_target_exit_data:
13968     case OMPD_target:
13969     case OMPD_target_simd:
13970     case OMPD_target_teams:
13971     case OMPD_target_parallel:
13972     case OMPD_target_teams_distribute:
13973     case OMPD_target_teams_distribute_simd:
13974     case OMPD_target_parallel_for:
13975     case OMPD_target_parallel_for_simd:
13976     case OMPD_target_teams_distribute_parallel_for:
13977     case OMPD_target_teams_distribute_parallel_for_simd:
13978     case OMPD_target_data:
13979     case OMPD_teams_distribute_parallel_for:
13980     case OMPD_teams_distribute_parallel_for_simd:
13981     case OMPD_teams:
13982     case OMPD_teams_distribute:
13983     case OMPD_teams_distribute_simd:
13984     case OMPD_distribute_parallel_for:
13985     case OMPD_distribute_parallel_for_simd:
13986     case OMPD_cancel:
13987     case OMPD_parallel:
13988     case OMPD_parallel_master:
13989     case OMPD_parallel_sections:
13990     case OMPD_parallel_for:
13991     case OMPD_parallel_for_simd:
13992     case OMPD_threadprivate:
13993     case OMPD_allocate:
13994     case OMPD_taskyield:
13995     case OMPD_barrier:
13996     case OMPD_taskwait:
13997     case OMPD_cancellation_point:
13998     case OMPD_flush:
13999     case OMPD_depobj:
14000     case OMPD_scan:
14001     case OMPD_declare_reduction:
14002     case OMPD_declare_mapper:
14003     case OMPD_declare_simd:
14004     case OMPD_declare_variant:
14005     case OMPD_begin_declare_variant:
14006     case OMPD_end_declare_variant:
14007     case OMPD_declare_target:
14008     case OMPD_end_declare_target:
14009     case OMPD_simd:
14010     case OMPD_tile:
14011     case OMPD_unroll:
14012     case OMPD_for:
14013     case OMPD_for_simd:
14014     case OMPD_sections:
14015     case OMPD_section:
14016     case OMPD_single:
14017     case OMPD_master:
14018     case OMPD_masked:
14019     case OMPD_critical:
14020     case OMPD_taskgroup:
14021     case OMPD_distribute:
14022     case OMPD_ordered:
14023     case OMPD_atomic:
14024     case OMPD_distribute_simd:
14025     case OMPD_requires:
14026     case OMPD_metadirective:
14027       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
14028     case OMPD_unknown:
14029     default:
14030       llvm_unreachable("Unknown OpenMP directive");
14031     }
14032     break;
14033   case OMPC_novariants:
14034   case OMPC_nocontext:
14035     switch (DKind) {
14036     case OMPD_dispatch:
14037       CaptureRegion = OMPD_task;
14038       break;
14039     default:
14040       llvm_unreachable("Unexpected OpenMP directive");
14041     }
14042     break;
14043   case OMPC_filter:
14044     // Do not capture filter-clause expressions.
14045     break;
14046   case OMPC_when:
14047     if (DKind == OMPD_metadirective) {
14048       CaptureRegion = OMPD_metadirective;
14049     } else if (DKind == OMPD_unknown) {
14050       llvm_unreachable("Unknown OpenMP directive");
14051     } else {
14052       llvm_unreachable("Unexpected OpenMP directive with when clause");
14053     }
14054     break;
14055   case OMPC_firstprivate:
14056   case OMPC_lastprivate:
14057   case OMPC_reduction:
14058   case OMPC_task_reduction:
14059   case OMPC_in_reduction:
14060   case OMPC_linear:
14061   case OMPC_default:
14062   case OMPC_proc_bind:
14063   case OMPC_safelen:
14064   case OMPC_simdlen:
14065   case OMPC_sizes:
14066   case OMPC_allocator:
14067   case OMPC_collapse:
14068   case OMPC_private:
14069   case OMPC_shared:
14070   case OMPC_aligned:
14071   case OMPC_copyin:
14072   case OMPC_copyprivate:
14073   case OMPC_ordered:
14074   case OMPC_nowait:
14075   case OMPC_untied:
14076   case OMPC_mergeable:
14077   case OMPC_threadprivate:
14078   case OMPC_allocate:
14079   case OMPC_flush:
14080   case OMPC_depobj:
14081   case OMPC_read:
14082   case OMPC_write:
14083   case OMPC_update:
14084   case OMPC_capture:
14085   case OMPC_seq_cst:
14086   case OMPC_acq_rel:
14087   case OMPC_acquire:
14088   case OMPC_release:
14089   case OMPC_relaxed:
14090   case OMPC_depend:
14091   case OMPC_threads:
14092   case OMPC_simd:
14093   case OMPC_map:
14094   case OMPC_nogroup:
14095   case OMPC_hint:
14096   case OMPC_defaultmap:
14097   case OMPC_unknown:
14098   case OMPC_uniform:
14099   case OMPC_to:
14100   case OMPC_from:
14101   case OMPC_use_device_ptr:
14102   case OMPC_use_device_addr:
14103   case OMPC_is_device_ptr:
14104   case OMPC_unified_address:
14105   case OMPC_unified_shared_memory:
14106   case OMPC_reverse_offload:
14107   case OMPC_dynamic_allocators:
14108   case OMPC_atomic_default_mem_order:
14109   case OMPC_device_type:
14110   case OMPC_match:
14111   case OMPC_nontemporal:
14112   case OMPC_order:
14113   case OMPC_destroy:
14114   case OMPC_detach:
14115   case OMPC_inclusive:
14116   case OMPC_exclusive:
14117   case OMPC_uses_allocators:
14118   case OMPC_affinity:
14119   default:
14120     llvm_unreachable("Unexpected OpenMP clause.");
14121   }
14122   return CaptureRegion;
14123 }
14124 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)14125 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
14126                                      Expr *Condition, SourceLocation StartLoc,
14127                                      SourceLocation LParenLoc,
14128                                      SourceLocation NameModifierLoc,
14129                                      SourceLocation ColonLoc,
14130                                      SourceLocation EndLoc) {
14131   Expr *ValExpr = Condition;
14132   Stmt *HelperValStmt = nullptr;
14133   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14134   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14135       !Condition->isInstantiationDependent() &&
14136       !Condition->containsUnexpandedParameterPack()) {
14137     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14138     if (Val.isInvalid())
14139       return nullptr;
14140 
14141     ValExpr = Val.get();
14142 
14143     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14144     CaptureRegion = getOpenMPCaptureRegionForClause(
14145         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
14146     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14147       ValExpr = MakeFullExpr(ValExpr).get();
14148       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14149       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14150       HelperValStmt = buildPreInits(Context, Captures);
14151     }
14152   }
14153 
14154   return new (Context)
14155       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
14156                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
14157 }
14158 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14159 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
14160                                         SourceLocation StartLoc,
14161                                         SourceLocation LParenLoc,
14162                                         SourceLocation EndLoc) {
14163   Expr *ValExpr = Condition;
14164   Stmt *HelperValStmt = nullptr;
14165   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14166   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14167       !Condition->isInstantiationDependent() &&
14168       !Condition->containsUnexpandedParameterPack()) {
14169     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14170     if (Val.isInvalid())
14171       return nullptr;
14172 
14173     ValExpr = MakeFullExpr(Val.get()).get();
14174 
14175     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14176     CaptureRegion =
14177         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
14178     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14179       ValExpr = MakeFullExpr(ValExpr).get();
14180       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14181       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14182       HelperValStmt = buildPreInits(Context, Captures);
14183     }
14184   }
14185 
14186   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
14187                                       StartLoc, LParenLoc, EndLoc);
14188 }
14189 
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)14190 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
14191                                                         Expr *Op) {
14192   if (!Op)
14193     return ExprError();
14194 
14195   class IntConvertDiagnoser : public ICEConvertDiagnoser {
14196   public:
14197     IntConvertDiagnoser()
14198         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
14199     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
14200                                          QualType T) override {
14201       return S.Diag(Loc, diag::err_omp_not_integral) << T;
14202     }
14203     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
14204                                              QualType T) override {
14205       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
14206     }
14207     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
14208                                                QualType T,
14209                                                QualType ConvTy) override {
14210       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
14211     }
14212     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
14213                                            QualType ConvTy) override {
14214       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14215              << ConvTy->isEnumeralType() << ConvTy;
14216     }
14217     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
14218                                             QualType T) override {
14219       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
14220     }
14221     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
14222                                         QualType ConvTy) override {
14223       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14224              << ConvTy->isEnumeralType() << ConvTy;
14225     }
14226     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
14227                                              QualType) override {
14228       llvm_unreachable("conversion functions are permitted");
14229     }
14230   } ConvertDiagnoser;
14231   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
14232 }
14233 
14234 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)14235 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
14236                           bool StrictlyPositive, bool BuildCapture = false,
14237                           OpenMPDirectiveKind DKind = OMPD_unknown,
14238                           OpenMPDirectiveKind *CaptureRegion = nullptr,
14239                           Stmt **HelperValStmt = nullptr) {
14240   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
14241       !ValExpr->isInstantiationDependent()) {
14242     SourceLocation Loc = ValExpr->getExprLoc();
14243     ExprResult Value =
14244         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
14245     if (Value.isInvalid())
14246       return false;
14247 
14248     ValExpr = Value.get();
14249     // The expression must evaluate to a non-negative integer value.
14250     if (Optional<llvm::APSInt> Result =
14251             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
14252       if (Result->isSigned() &&
14253           !((!StrictlyPositive && Result->isNonNegative()) ||
14254             (StrictlyPositive && Result->isStrictlyPositive()))) {
14255         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
14256             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14257             << ValExpr->getSourceRange();
14258         return false;
14259       }
14260     }
14261     if (!BuildCapture)
14262       return true;
14263     *CaptureRegion =
14264         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
14265     if (*CaptureRegion != OMPD_unknown &&
14266         !SemaRef.CurContext->isDependentContext()) {
14267       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
14268       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14269       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
14270       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
14271     }
14272   }
14273   return true;
14274 }
14275 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14276 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
14277                                              SourceLocation StartLoc,
14278                                              SourceLocation LParenLoc,
14279                                              SourceLocation EndLoc) {
14280   Expr *ValExpr = NumThreads;
14281   Stmt *HelperValStmt = nullptr;
14282 
14283   // OpenMP [2.5, Restrictions]
14284   //  The num_threads expression must evaluate to a positive integer value.
14285   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
14286                                  /*StrictlyPositive=*/true))
14287     return nullptr;
14288 
14289   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14290   OpenMPDirectiveKind CaptureRegion =
14291       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
14292   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14293     ValExpr = MakeFullExpr(ValExpr).get();
14294     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14295     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14296     HelperValStmt = buildPreInits(Context, Captures);
14297   }
14298 
14299   return new (Context) OMPNumThreadsClause(
14300       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14301 }
14302 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive,bool SuppressExprDiags)14303 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
14304                                                        OpenMPClauseKind CKind,
14305                                                        bool StrictlyPositive,
14306                                                        bool SuppressExprDiags) {
14307   if (!E)
14308     return ExprError();
14309   if (E->isValueDependent() || E->isTypeDependent() ||
14310       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14311     return E;
14312 
14313   llvm::APSInt Result;
14314   ExprResult ICE;
14315   if (SuppressExprDiags) {
14316     // Use a custom diagnoser that suppresses 'note' diagnostics about the
14317     // expression.
14318     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
14319       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
14320       Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
14321                                                  SourceLocation Loc) override {
14322         llvm_unreachable("Diagnostic suppressed");
14323       }
14324     } Diagnoser;
14325     ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
14326   } else {
14327     ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
14328   }
14329   if (ICE.isInvalid())
14330     return ExprError();
14331 
14332   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
14333       (!StrictlyPositive && !Result.isNonNegative())) {
14334     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
14335         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14336         << E->getSourceRange();
14337     return ExprError();
14338   }
14339   if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
14340     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
14341         << E->getSourceRange();
14342     return ExprError();
14343   }
14344   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
14345     DSAStack->setAssociatedLoops(Result.getExtValue());
14346   else if (CKind == OMPC_ordered)
14347     DSAStack->setAssociatedLoops(Result.getExtValue());
14348   return ICE;
14349 }
14350 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14351 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
14352                                           SourceLocation LParenLoc,
14353                                           SourceLocation EndLoc) {
14354   // OpenMP [2.8.1, simd construct, Description]
14355   // The parameter of the safelen clause must be a constant
14356   // positive integer expression.
14357   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
14358   if (Safelen.isInvalid())
14359     return nullptr;
14360   return new (Context)
14361       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
14362 }
14363 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14364 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
14365                                           SourceLocation LParenLoc,
14366                                           SourceLocation EndLoc) {
14367   // OpenMP [2.8.1, simd construct, Description]
14368   // The parameter of the simdlen clause must be a constant
14369   // positive integer expression.
14370   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
14371   if (Simdlen.isInvalid())
14372     return nullptr;
14373   return new (Context)
14374       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
14375 }
14376 
14377 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)14378 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
14379                                     DSAStackTy *Stack) {
14380   QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
14381   if (!OMPAllocatorHandleT.isNull())
14382     return true;
14383   // Build the predefined allocator expressions.
14384   bool ErrorFound = false;
14385   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
14386     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
14387     StringRef Allocator =
14388         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
14389     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
14390     auto *VD = dyn_cast_or_null<ValueDecl>(
14391         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
14392     if (!VD) {
14393       ErrorFound = true;
14394       break;
14395     }
14396     QualType AllocatorType =
14397         VD->getType().getNonLValueExprType(S.getASTContext());
14398     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
14399     if (!Res.isUsable()) {
14400       ErrorFound = true;
14401       break;
14402     }
14403     if (OMPAllocatorHandleT.isNull())
14404       OMPAllocatorHandleT = AllocatorType;
14405     if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
14406       ErrorFound = true;
14407       break;
14408     }
14409     Stack->setAllocator(AllocatorKind, Res.get());
14410   }
14411   if (ErrorFound) {
14412     S.Diag(Loc, diag::err_omp_implied_type_not_found)
14413         << "omp_allocator_handle_t";
14414     return false;
14415   }
14416   OMPAllocatorHandleT.addConst();
14417   Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
14418   return true;
14419 }
14420 
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14421 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
14422                                             SourceLocation LParenLoc,
14423                                             SourceLocation EndLoc) {
14424   // OpenMP [2.11.3, allocate Directive, Description]
14425   // allocator is an expression of omp_allocator_handle_t type.
14426   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
14427     return nullptr;
14428 
14429   ExprResult Allocator = DefaultLvalueConversion(A);
14430   if (Allocator.isInvalid())
14431     return nullptr;
14432   Allocator = PerformImplicitConversion(Allocator.get(),
14433                                         DSAStack->getOMPAllocatorHandleT(),
14434                                         Sema::AA_Initializing,
14435                                         /*AllowExplicit=*/true);
14436   if (Allocator.isInvalid())
14437     return nullptr;
14438   return new (Context)
14439       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
14440 }
14441 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14442 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
14443                                            SourceLocation StartLoc,
14444                                            SourceLocation LParenLoc,
14445                                            SourceLocation EndLoc) {
14446   // OpenMP [2.7.1, loop construct, Description]
14447   // OpenMP [2.8.1, simd construct, Description]
14448   // OpenMP [2.9.6, distribute construct, Description]
14449   // The parameter of the collapse clause must be a constant
14450   // positive integer expression.
14451   ExprResult NumForLoopsResult =
14452       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
14453   if (NumForLoopsResult.isInvalid())
14454     return nullptr;
14455   return new (Context)
14456       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
14457 }
14458 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)14459 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
14460                                           SourceLocation EndLoc,
14461                                           SourceLocation LParenLoc,
14462                                           Expr *NumForLoops) {
14463   // OpenMP [2.7.1, loop construct, Description]
14464   // OpenMP [2.8.1, simd construct, Description]
14465   // OpenMP [2.9.6, distribute construct, Description]
14466   // The parameter of the ordered clause must be a constant
14467   // positive integer expression if any.
14468   if (NumForLoops && LParenLoc.isValid()) {
14469     ExprResult NumForLoopsResult =
14470         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
14471     if (NumForLoopsResult.isInvalid())
14472       return nullptr;
14473     NumForLoops = NumForLoopsResult.get();
14474   } else {
14475     NumForLoops = nullptr;
14476   }
14477   auto *Clause = OMPOrderedClause::Create(
14478       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
14479       StartLoc, LParenLoc, EndLoc);
14480   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
14481   return Clause;
14482 }
14483 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14484 OMPClause *Sema::ActOnOpenMPSimpleClause(
14485     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
14486     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14487   OMPClause *Res = nullptr;
14488   switch (Kind) {
14489   case OMPC_default:
14490     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
14491                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14492     break;
14493   case OMPC_proc_bind:
14494     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
14495                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14496     break;
14497   case OMPC_atomic_default_mem_order:
14498     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14499         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14500         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14501     break;
14502   case OMPC_order:
14503     Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14504                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14505     break;
14506   case OMPC_update:
14507     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14508                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14509     break;
14510   case OMPC_if:
14511   case OMPC_final:
14512   case OMPC_num_threads:
14513   case OMPC_safelen:
14514   case OMPC_simdlen:
14515   case OMPC_sizes:
14516   case OMPC_allocator:
14517   case OMPC_collapse:
14518   case OMPC_schedule:
14519   case OMPC_private:
14520   case OMPC_firstprivate:
14521   case OMPC_lastprivate:
14522   case OMPC_shared:
14523   case OMPC_reduction:
14524   case OMPC_task_reduction:
14525   case OMPC_in_reduction:
14526   case OMPC_linear:
14527   case OMPC_aligned:
14528   case OMPC_copyin:
14529   case OMPC_copyprivate:
14530   case OMPC_ordered:
14531   case OMPC_nowait:
14532   case OMPC_untied:
14533   case OMPC_mergeable:
14534   case OMPC_threadprivate:
14535   case OMPC_allocate:
14536   case OMPC_flush:
14537   case OMPC_depobj:
14538   case OMPC_read:
14539   case OMPC_write:
14540   case OMPC_capture:
14541   case OMPC_seq_cst:
14542   case OMPC_acq_rel:
14543   case OMPC_acquire:
14544   case OMPC_release:
14545   case OMPC_relaxed:
14546   case OMPC_depend:
14547   case OMPC_device:
14548   case OMPC_threads:
14549   case OMPC_simd:
14550   case OMPC_map:
14551   case OMPC_num_teams:
14552   case OMPC_thread_limit:
14553   case OMPC_priority:
14554   case OMPC_grainsize:
14555   case OMPC_nogroup:
14556   case OMPC_num_tasks:
14557   case OMPC_hint:
14558   case OMPC_dist_schedule:
14559   case OMPC_defaultmap:
14560   case OMPC_unknown:
14561   case OMPC_uniform:
14562   case OMPC_to:
14563   case OMPC_from:
14564   case OMPC_use_device_ptr:
14565   case OMPC_use_device_addr:
14566   case OMPC_is_device_ptr:
14567   case OMPC_unified_address:
14568   case OMPC_unified_shared_memory:
14569   case OMPC_reverse_offload:
14570   case OMPC_dynamic_allocators:
14571   case OMPC_device_type:
14572   case OMPC_match:
14573   case OMPC_nontemporal:
14574   case OMPC_destroy:
14575   case OMPC_novariants:
14576   case OMPC_nocontext:
14577   case OMPC_detach:
14578   case OMPC_inclusive:
14579   case OMPC_exclusive:
14580   case OMPC_uses_allocators:
14581   case OMPC_affinity:
14582   case OMPC_when:
14583   default:
14584     llvm_unreachable("Clause is not allowed.");
14585   }
14586   return Res;
14587 }
14588 
14589 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)14590 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14591                         ArrayRef<unsigned> Exclude = llvm::None) {
14592   SmallString<256> Buffer;
14593   llvm::raw_svector_ostream Out(Buffer);
14594   unsigned Skipped = Exclude.size();
14595   auto S = Exclude.begin(), E = Exclude.end();
14596   for (unsigned I = First; I < Last; ++I) {
14597     if (std::find(S, E, I) != E) {
14598       --Skipped;
14599       continue;
14600     }
14601     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14602     if (I + Skipped + 2 == Last)
14603       Out << " or ";
14604     else if (I + Skipped + 1 != Last)
14605       Out << ", ";
14606   }
14607   return std::string(Out.str());
14608 }
14609 
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14610 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14611                                           SourceLocation KindKwLoc,
14612                                           SourceLocation StartLoc,
14613                                           SourceLocation LParenLoc,
14614                                           SourceLocation EndLoc) {
14615   if (Kind == OMP_DEFAULT_unknown) {
14616     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14617         << getListOfPossibleValues(OMPC_default, /*First=*/0,
14618                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
14619         << getOpenMPClauseName(OMPC_default);
14620     return nullptr;
14621   }
14622 
14623   switch (Kind) {
14624   case OMP_DEFAULT_none:
14625     DSAStack->setDefaultDSANone(KindKwLoc);
14626     break;
14627   case OMP_DEFAULT_shared:
14628     DSAStack->setDefaultDSAShared(KindKwLoc);
14629     break;
14630   case OMP_DEFAULT_firstprivate:
14631     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
14632     break;
14633   default:
14634     llvm_unreachable("DSA unexpected in OpenMP default clause");
14635   }
14636 
14637   return new (Context)
14638       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14639 }
14640 
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14641 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14642                                            SourceLocation KindKwLoc,
14643                                            SourceLocation StartLoc,
14644                                            SourceLocation LParenLoc,
14645                                            SourceLocation EndLoc) {
14646   if (Kind == OMP_PROC_BIND_unknown) {
14647     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14648         << getListOfPossibleValues(OMPC_proc_bind,
14649                                    /*First=*/unsigned(OMP_PROC_BIND_master),
14650                                    /*Last=*/
14651                                    unsigned(LangOpts.OpenMP > 50
14652                                                 ? OMP_PROC_BIND_primary
14653                                                 : OMP_PROC_BIND_spread) +
14654                                        1)
14655         << getOpenMPClauseName(OMPC_proc_bind);
14656     return nullptr;
14657   }
14658   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14659     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14660         << getListOfPossibleValues(OMPC_proc_bind,
14661                                    /*First=*/unsigned(OMP_PROC_BIND_master),
14662                                    /*Last=*/
14663                                    unsigned(OMP_PROC_BIND_spread) + 1)
14664         << getOpenMPClauseName(OMPC_proc_bind);
14665   return new (Context)
14666       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14667 }
14668 
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14669 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14670     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14671     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14672   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14673     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14674         << getListOfPossibleValues(
14675                OMPC_atomic_default_mem_order, /*First=*/0,
14676                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14677         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14678     return nullptr;
14679   }
14680   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14681                                                       LParenLoc, EndLoc);
14682 }
14683 
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14684 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14685                                         SourceLocation KindKwLoc,
14686                                         SourceLocation StartLoc,
14687                                         SourceLocation LParenLoc,
14688                                         SourceLocation EndLoc) {
14689   if (Kind == OMPC_ORDER_unknown) {
14690     static_assert(OMPC_ORDER_unknown > 0,
14691                   "OMPC_ORDER_unknown not greater than 0");
14692     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14693         << getListOfPossibleValues(OMPC_order, /*First=*/0,
14694                                    /*Last=*/OMPC_ORDER_unknown)
14695         << getOpenMPClauseName(OMPC_order);
14696     return nullptr;
14697   }
14698   return new (Context)
14699       OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14700 }
14701 
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14702 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14703                                          SourceLocation KindKwLoc,
14704                                          SourceLocation StartLoc,
14705                                          SourceLocation LParenLoc,
14706                                          SourceLocation EndLoc) {
14707   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14708       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14709     unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14710                          OMPC_DEPEND_depobj};
14711     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14712         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14713                                    /*Last=*/OMPC_DEPEND_unknown, Except)
14714         << getOpenMPClauseName(OMPC_update);
14715     return nullptr;
14716   }
14717   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14718                                  EndLoc);
14719 }
14720 
ActOnOpenMPSizesClause(ArrayRef<Expr * > SizeExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14721 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14722                                         SourceLocation StartLoc,
14723                                         SourceLocation LParenLoc,
14724                                         SourceLocation EndLoc) {
14725   for (Expr *SizeExpr : SizeExprs) {
14726     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14727         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14728     if (!NumForLoopsResult.isUsable())
14729       return nullptr;
14730   }
14731 
14732   DSAStack->setAssociatedLoops(SizeExprs.size());
14733   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14734                                 SizeExprs);
14735 }
14736 
ActOnOpenMPFullClause(SourceLocation StartLoc,SourceLocation EndLoc)14737 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
14738                                        SourceLocation EndLoc) {
14739   return OMPFullClause::Create(Context, StartLoc, EndLoc);
14740 }
14741 
ActOnOpenMPPartialClause(Expr * FactorExpr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14742 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
14743                                           SourceLocation StartLoc,
14744                                           SourceLocation LParenLoc,
14745                                           SourceLocation EndLoc) {
14746   if (FactorExpr) {
14747     // If an argument is specified, it must be a constant (or an unevaluated
14748     // template expression).
14749     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
14750         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
14751     if (FactorResult.isInvalid())
14752       return nullptr;
14753     FactorExpr = FactorResult.get();
14754   }
14755 
14756   return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14757                                   FactorExpr);
14758 }
14759 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)14760 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14761     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14762     SourceLocation StartLoc, SourceLocation LParenLoc,
14763     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14764     SourceLocation EndLoc) {
14765   OMPClause *Res = nullptr;
14766   switch (Kind) {
14767   case OMPC_schedule:
14768     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14769     assert(Argument.size() == NumberOfElements &&
14770            ArgumentLoc.size() == NumberOfElements);
14771     Res = ActOnOpenMPScheduleClause(
14772         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14773         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14774         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14775         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14776         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14777     break;
14778   case OMPC_if:
14779     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14780     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14781                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14782                               DelimLoc, EndLoc);
14783     break;
14784   case OMPC_dist_schedule:
14785     Res = ActOnOpenMPDistScheduleClause(
14786         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14787         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14788     break;
14789   case OMPC_defaultmap:
14790     enum { Modifier, DefaultmapKind };
14791     Res = ActOnOpenMPDefaultmapClause(
14792         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14793         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14794         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14795         EndLoc);
14796     break;
14797   case OMPC_device:
14798     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14799     Res = ActOnOpenMPDeviceClause(
14800         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14801         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14802     break;
14803   case OMPC_final:
14804   case OMPC_num_threads:
14805   case OMPC_safelen:
14806   case OMPC_simdlen:
14807   case OMPC_sizes:
14808   case OMPC_allocator:
14809   case OMPC_collapse:
14810   case OMPC_default:
14811   case OMPC_proc_bind:
14812   case OMPC_private:
14813   case OMPC_firstprivate:
14814   case OMPC_lastprivate:
14815   case OMPC_shared:
14816   case OMPC_reduction:
14817   case OMPC_task_reduction:
14818   case OMPC_in_reduction:
14819   case OMPC_linear:
14820   case OMPC_aligned:
14821   case OMPC_copyin:
14822   case OMPC_copyprivate:
14823   case OMPC_ordered:
14824   case OMPC_nowait:
14825   case OMPC_untied:
14826   case OMPC_mergeable:
14827   case OMPC_threadprivate:
14828   case OMPC_allocate:
14829   case OMPC_flush:
14830   case OMPC_depobj:
14831   case OMPC_read:
14832   case OMPC_write:
14833   case OMPC_update:
14834   case OMPC_capture:
14835   case OMPC_seq_cst:
14836   case OMPC_acq_rel:
14837   case OMPC_acquire:
14838   case OMPC_release:
14839   case OMPC_relaxed:
14840   case OMPC_depend:
14841   case OMPC_threads:
14842   case OMPC_simd:
14843   case OMPC_map:
14844   case OMPC_num_teams:
14845   case OMPC_thread_limit:
14846   case OMPC_priority:
14847   case OMPC_grainsize:
14848   case OMPC_nogroup:
14849   case OMPC_num_tasks:
14850   case OMPC_hint:
14851   case OMPC_unknown:
14852   case OMPC_uniform:
14853   case OMPC_to:
14854   case OMPC_from:
14855   case OMPC_use_device_ptr:
14856   case OMPC_use_device_addr:
14857   case OMPC_is_device_ptr:
14858   case OMPC_unified_address:
14859   case OMPC_unified_shared_memory:
14860   case OMPC_reverse_offload:
14861   case OMPC_dynamic_allocators:
14862   case OMPC_atomic_default_mem_order:
14863   case OMPC_device_type:
14864   case OMPC_match:
14865   case OMPC_nontemporal:
14866   case OMPC_order:
14867   case OMPC_destroy:
14868   case OMPC_novariants:
14869   case OMPC_nocontext:
14870   case OMPC_detach:
14871   case OMPC_inclusive:
14872   case OMPC_exclusive:
14873   case OMPC_uses_allocators:
14874   case OMPC_affinity:
14875   case OMPC_when:
14876   default:
14877     llvm_unreachable("Clause is not allowed.");
14878   }
14879   return Res;
14880 }
14881 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)14882 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14883                                    OpenMPScheduleClauseModifier M2,
14884                                    SourceLocation M1Loc, SourceLocation M2Loc) {
14885   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14886     SmallVector<unsigned, 2> Excluded;
14887     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14888       Excluded.push_back(M2);
14889     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14890       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14891     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14892       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14893     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14894         << getListOfPossibleValues(OMPC_schedule,
14895                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14896                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14897                                    Excluded)
14898         << getOpenMPClauseName(OMPC_schedule);
14899     return true;
14900   }
14901   return false;
14902 }
14903 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)14904 OMPClause *Sema::ActOnOpenMPScheduleClause(
14905     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14906     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14907     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14908     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14909   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14910       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14911     return nullptr;
14912   // OpenMP, 2.7.1, Loop Construct, Restrictions
14913   // Either the monotonic modifier or the nonmonotonic modifier can be specified
14914   // but not both.
14915   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14916       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14917        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14918       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14919        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14920     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14921         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14922         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14923     return nullptr;
14924   }
14925   if (Kind == OMPC_SCHEDULE_unknown) {
14926     std::string Values;
14927     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14928       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14929       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14930                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14931                                        Exclude);
14932     } else {
14933       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14934                                        /*Last=*/OMPC_SCHEDULE_unknown);
14935     }
14936     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14937         << Values << getOpenMPClauseName(OMPC_schedule);
14938     return nullptr;
14939   }
14940   // OpenMP, 2.7.1, Loop Construct, Restrictions
14941   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14942   // schedule(guided).
14943   // OpenMP 5.0 does not have this restriction.
14944   if (LangOpts.OpenMP < 50 &&
14945       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14946        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14947       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14948     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14949          diag::err_omp_schedule_nonmonotonic_static);
14950     return nullptr;
14951   }
14952   Expr *ValExpr = ChunkSize;
14953   Stmt *HelperValStmt = nullptr;
14954   if (ChunkSize) {
14955     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14956         !ChunkSize->isInstantiationDependent() &&
14957         !ChunkSize->containsUnexpandedParameterPack()) {
14958       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14959       ExprResult Val =
14960           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14961       if (Val.isInvalid())
14962         return nullptr;
14963 
14964       ValExpr = Val.get();
14965 
14966       // OpenMP [2.7.1, Restrictions]
14967       //  chunk_size must be a loop invariant integer expression with a positive
14968       //  value.
14969       if (Optional<llvm::APSInt> Result =
14970               ValExpr->getIntegerConstantExpr(Context)) {
14971         if (Result->isSigned() && !Result->isStrictlyPositive()) {
14972           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14973               << "schedule" << 1 << ChunkSize->getSourceRange();
14974           return nullptr;
14975         }
14976       } else if (getOpenMPCaptureRegionForClause(
14977                      DSAStack->getCurrentDirective(), OMPC_schedule,
14978                      LangOpts.OpenMP) != OMPD_unknown &&
14979                  !CurContext->isDependentContext()) {
14980         ValExpr = MakeFullExpr(ValExpr).get();
14981         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14982         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14983         HelperValStmt = buildPreInits(Context, Captures);
14984       }
14985     }
14986   }
14987 
14988   return new (Context)
14989       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14990                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14991 }
14992 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)14993 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14994                                    SourceLocation StartLoc,
14995                                    SourceLocation EndLoc) {
14996   OMPClause *Res = nullptr;
14997   switch (Kind) {
14998   case OMPC_ordered:
14999     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
15000     break;
15001   case OMPC_nowait:
15002     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
15003     break;
15004   case OMPC_untied:
15005     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
15006     break;
15007   case OMPC_mergeable:
15008     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
15009     break;
15010   case OMPC_read:
15011     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
15012     break;
15013   case OMPC_write:
15014     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
15015     break;
15016   case OMPC_update:
15017     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
15018     break;
15019   case OMPC_capture:
15020     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
15021     break;
15022   case OMPC_seq_cst:
15023     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
15024     break;
15025   case OMPC_acq_rel:
15026     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
15027     break;
15028   case OMPC_acquire:
15029     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
15030     break;
15031   case OMPC_release:
15032     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
15033     break;
15034   case OMPC_relaxed:
15035     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
15036     break;
15037   case OMPC_threads:
15038     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
15039     break;
15040   case OMPC_simd:
15041     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
15042     break;
15043   case OMPC_nogroup:
15044     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
15045     break;
15046   case OMPC_unified_address:
15047     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
15048     break;
15049   case OMPC_unified_shared_memory:
15050     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
15051     break;
15052   case OMPC_reverse_offload:
15053     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
15054     break;
15055   case OMPC_dynamic_allocators:
15056     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
15057     break;
15058   case OMPC_destroy:
15059     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
15060                                    /*LParenLoc=*/SourceLocation(),
15061                                    /*VarLoc=*/SourceLocation(), EndLoc);
15062     break;
15063   case OMPC_full:
15064     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
15065     break;
15066   case OMPC_partial:
15067     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
15068     break;
15069   case OMPC_if:
15070   case OMPC_final:
15071   case OMPC_num_threads:
15072   case OMPC_safelen:
15073   case OMPC_simdlen:
15074   case OMPC_sizes:
15075   case OMPC_allocator:
15076   case OMPC_collapse:
15077   case OMPC_schedule:
15078   case OMPC_private:
15079   case OMPC_firstprivate:
15080   case OMPC_lastprivate:
15081   case OMPC_shared:
15082   case OMPC_reduction:
15083   case OMPC_task_reduction:
15084   case OMPC_in_reduction:
15085   case OMPC_linear:
15086   case OMPC_aligned:
15087   case OMPC_copyin:
15088   case OMPC_copyprivate:
15089   case OMPC_default:
15090   case OMPC_proc_bind:
15091   case OMPC_threadprivate:
15092   case OMPC_allocate:
15093   case OMPC_flush:
15094   case OMPC_depobj:
15095   case OMPC_depend:
15096   case OMPC_device:
15097   case OMPC_map:
15098   case OMPC_num_teams:
15099   case OMPC_thread_limit:
15100   case OMPC_priority:
15101   case OMPC_grainsize:
15102   case OMPC_num_tasks:
15103   case OMPC_hint:
15104   case OMPC_dist_schedule:
15105   case OMPC_defaultmap:
15106   case OMPC_unknown:
15107   case OMPC_uniform:
15108   case OMPC_to:
15109   case OMPC_from:
15110   case OMPC_use_device_ptr:
15111   case OMPC_use_device_addr:
15112   case OMPC_is_device_ptr:
15113   case OMPC_atomic_default_mem_order:
15114   case OMPC_device_type:
15115   case OMPC_match:
15116   case OMPC_nontemporal:
15117   case OMPC_order:
15118   case OMPC_novariants:
15119   case OMPC_nocontext:
15120   case OMPC_detach:
15121   case OMPC_inclusive:
15122   case OMPC_exclusive:
15123   case OMPC_uses_allocators:
15124   case OMPC_affinity:
15125   case OMPC_when:
15126   default:
15127     llvm_unreachable("Clause is not allowed.");
15128   }
15129   return Res;
15130 }
15131 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)15132 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
15133                                          SourceLocation EndLoc) {
15134   DSAStack->setNowaitRegion();
15135   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
15136 }
15137 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)15138 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
15139                                          SourceLocation EndLoc) {
15140   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
15141 }
15142 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)15143 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
15144                                             SourceLocation EndLoc) {
15145   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
15146 }
15147 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)15148 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
15149                                        SourceLocation EndLoc) {
15150   return new (Context) OMPReadClause(StartLoc, EndLoc);
15151 }
15152 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)15153 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
15154                                         SourceLocation EndLoc) {
15155   return new (Context) OMPWriteClause(StartLoc, EndLoc);
15156 }
15157 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)15158 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
15159                                          SourceLocation EndLoc) {
15160   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
15161 }
15162 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)15163 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
15164                                           SourceLocation EndLoc) {
15165   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
15166 }
15167 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)15168 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
15169                                          SourceLocation EndLoc) {
15170   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
15171 }
15172 
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)15173 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
15174                                          SourceLocation EndLoc) {
15175   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
15176 }
15177 
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)15178 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
15179                                           SourceLocation EndLoc) {
15180   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
15181 }
15182 
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)15183 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
15184                                           SourceLocation EndLoc) {
15185   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
15186 }
15187 
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)15188 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
15189                                           SourceLocation EndLoc) {
15190   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
15191 }
15192 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)15193 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
15194                                           SourceLocation EndLoc) {
15195   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
15196 }
15197 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)15198 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
15199                                        SourceLocation EndLoc) {
15200   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
15201 }
15202 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)15203 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
15204                                           SourceLocation EndLoc) {
15205   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
15206 }
15207 
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)15208 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
15209                                                  SourceLocation EndLoc) {
15210   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
15211 }
15212 
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)15213 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
15214                                                       SourceLocation EndLoc) {
15215   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
15216 }
15217 
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)15218 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
15219                                                  SourceLocation EndLoc) {
15220   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
15221 }
15222 
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)15223 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
15224                                                     SourceLocation EndLoc) {
15225   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
15226 }
15227 
ActOnOpenMPInteropDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)15228 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
15229                                              SourceLocation StartLoc,
15230                                              SourceLocation EndLoc) {
15231 
15232   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15233   // At least one action-clause must appear on a directive.
15234   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
15235     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
15236     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
15237         << Expected << getOpenMPDirectiveName(OMPD_interop);
15238     return StmtError();
15239   }
15240 
15241   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15242   // A depend clause can only appear on the directive if a targetsync
15243   // interop-type is present or the interop-var was initialized with
15244   // the targetsync interop-type.
15245 
15246   // If there is any 'init' clause diagnose if there is no 'init' clause with
15247   // interop-type of 'targetsync'. Cases involving other directives cannot be
15248   // diagnosed.
15249   const OMPDependClause *DependClause = nullptr;
15250   bool HasInitClause = false;
15251   bool IsTargetSync = false;
15252   for (const OMPClause *C : Clauses) {
15253     if (IsTargetSync)
15254       break;
15255     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
15256       HasInitClause = true;
15257       if (InitClause->getIsTargetSync())
15258         IsTargetSync = true;
15259     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
15260       DependClause = DC;
15261     }
15262   }
15263   if (DependClause && HasInitClause && !IsTargetSync) {
15264     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
15265     return StmtError();
15266   }
15267 
15268   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15269   // Each interop-var may be specified for at most one action-clause of each
15270   // interop construct.
15271   llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
15272   for (const OMPClause *C : Clauses) {
15273     OpenMPClauseKind ClauseKind = C->getClauseKind();
15274     const DeclRefExpr *DRE = nullptr;
15275     SourceLocation VarLoc;
15276 
15277     if (ClauseKind == OMPC_init) {
15278       const auto *IC = cast<OMPInitClause>(C);
15279       VarLoc = IC->getVarLoc();
15280       DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
15281     } else if (ClauseKind == OMPC_use) {
15282       const auto *UC = cast<OMPUseClause>(C);
15283       VarLoc = UC->getVarLoc();
15284       DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
15285     } else if (ClauseKind == OMPC_destroy) {
15286       const auto *DC = cast<OMPDestroyClause>(C);
15287       VarLoc = DC->getVarLoc();
15288       DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
15289     }
15290 
15291     if (!DRE)
15292       continue;
15293 
15294     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
15295       if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
15296         Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
15297         return StmtError();
15298       }
15299     }
15300   }
15301 
15302   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
15303 }
15304 
isValidInteropVariable(Sema & SemaRef,Expr * InteropVarExpr,SourceLocation VarLoc,OpenMPClauseKind Kind)15305 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
15306                                    SourceLocation VarLoc,
15307                                    OpenMPClauseKind Kind) {
15308   if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
15309       InteropVarExpr->isInstantiationDependent() ||
15310       InteropVarExpr->containsUnexpandedParameterPack())
15311     return true;
15312 
15313   const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
15314   if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
15315     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
15316     return false;
15317   }
15318 
15319   // Interop variable should be of type omp_interop_t.
15320   bool HasError = false;
15321   QualType InteropType;
15322   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
15323                       VarLoc, Sema::LookupOrdinaryName);
15324   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
15325     NamedDecl *ND = Result.getFoundDecl();
15326     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
15327       InteropType = QualType(TD->getTypeForDecl(), 0);
15328     } else {
15329       HasError = true;
15330     }
15331   } else {
15332     HasError = true;
15333   }
15334 
15335   if (HasError) {
15336     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
15337         << "omp_interop_t";
15338     return false;
15339   }
15340 
15341   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
15342   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
15343     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
15344     return false;
15345   }
15346 
15347   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15348   // The interop-var passed to init or destroy must be non-const.
15349   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
15350       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
15351     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
15352         << /*non-const*/ 1;
15353     return false;
15354   }
15355   return true;
15356 }
15357 
15358 OMPClause *
ActOnOpenMPInitClause(Expr * InteropVar,ArrayRef<Expr * > PrefExprs,bool IsTarget,bool IsTargetSync,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)15359 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
15360                             bool IsTarget, bool IsTargetSync,
15361                             SourceLocation StartLoc, SourceLocation LParenLoc,
15362                             SourceLocation VarLoc, SourceLocation EndLoc) {
15363 
15364   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
15365     return nullptr;
15366 
15367   // Check prefer_type values.  These foreign-runtime-id values are either
15368   // string literals or constant integral expressions.
15369   for (const Expr *E : PrefExprs) {
15370     if (E->isValueDependent() || E->isTypeDependent() ||
15371         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15372       continue;
15373     if (E->isIntegerConstantExpr(Context))
15374       continue;
15375     if (isa<StringLiteral>(E))
15376       continue;
15377     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
15378     return nullptr;
15379   }
15380 
15381   return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
15382                                IsTargetSync, StartLoc, LParenLoc, VarLoc,
15383                                EndLoc);
15384 }
15385 
ActOnOpenMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)15386 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
15387                                       SourceLocation LParenLoc,
15388                                       SourceLocation VarLoc,
15389                                       SourceLocation EndLoc) {
15390 
15391   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
15392     return nullptr;
15393 
15394   return new (Context)
15395       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15396 }
15397 
ActOnOpenMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)15398 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
15399                                           SourceLocation StartLoc,
15400                                           SourceLocation LParenLoc,
15401                                           SourceLocation VarLoc,
15402                                           SourceLocation EndLoc) {
15403   if (InteropVar &&
15404       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
15405     return nullptr;
15406 
15407   return new (Context)
15408       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15409 }
15410 
ActOnOpenMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15411 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
15412                                              SourceLocation StartLoc,
15413                                              SourceLocation LParenLoc,
15414                                              SourceLocation EndLoc) {
15415   Expr *ValExpr = Condition;
15416   Stmt *HelperValStmt = nullptr;
15417   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15418   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15419       !Condition->isInstantiationDependent() &&
15420       !Condition->containsUnexpandedParameterPack()) {
15421     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15422     if (Val.isInvalid())
15423       return nullptr;
15424 
15425     ValExpr = MakeFullExpr(Val.get()).get();
15426 
15427     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15428     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
15429                                                     LangOpts.OpenMP);
15430     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15431       ValExpr = MakeFullExpr(ValExpr).get();
15432       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15433       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15434       HelperValStmt = buildPreInits(Context, Captures);
15435     }
15436   }
15437 
15438   return new (Context) OMPNovariantsClause(
15439       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15440 }
15441 
ActOnOpenMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15442 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
15443                                             SourceLocation StartLoc,
15444                                             SourceLocation LParenLoc,
15445                                             SourceLocation EndLoc) {
15446   Expr *ValExpr = Condition;
15447   Stmt *HelperValStmt = nullptr;
15448   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15449   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15450       !Condition->isInstantiationDependent() &&
15451       !Condition->containsUnexpandedParameterPack()) {
15452     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15453     if (Val.isInvalid())
15454       return nullptr;
15455 
15456     ValExpr = MakeFullExpr(Val.get()).get();
15457 
15458     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15459     CaptureRegion =
15460         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
15461     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15462       ValExpr = MakeFullExpr(ValExpr).get();
15463       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15464       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15465       HelperValStmt = buildPreInits(Context, Captures);
15466     }
15467   }
15468 
15469   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
15470                                           StartLoc, LParenLoc, EndLoc);
15471 }
15472 
ActOnOpenMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15473 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
15474                                          SourceLocation StartLoc,
15475                                          SourceLocation LParenLoc,
15476                                          SourceLocation EndLoc) {
15477   Expr *ValExpr = ThreadID;
15478   Stmt *HelperValStmt = nullptr;
15479 
15480   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15481   OpenMPDirectiveKind CaptureRegion =
15482       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
15483   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15484     ValExpr = MakeFullExpr(ValExpr).get();
15485     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15486     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15487     HelperValStmt = buildPreInits(Context, Captures);
15488   }
15489 
15490   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
15491                                        StartLoc, LParenLoc, EndLoc);
15492 }
15493 
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)15494 OMPClause *Sema::ActOnOpenMPVarListClause(
15495     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
15496     const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
15497     CXXScopeSpec &ReductionOrMapperIdScopeSpec,
15498     DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
15499     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15500     ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
15501     SourceLocation ExtraModifierLoc,
15502     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
15503     ArrayRef<SourceLocation> MotionModifiersLoc) {
15504   SourceLocation StartLoc = Locs.StartLoc;
15505   SourceLocation LParenLoc = Locs.LParenLoc;
15506   SourceLocation EndLoc = Locs.EndLoc;
15507   OMPClause *Res = nullptr;
15508   switch (Kind) {
15509   case OMPC_private:
15510     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15511     break;
15512   case OMPC_firstprivate:
15513     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15514     break;
15515   case OMPC_lastprivate:
15516     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
15517            "Unexpected lastprivate modifier.");
15518     Res = ActOnOpenMPLastprivateClause(
15519         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
15520         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
15521     break;
15522   case OMPC_shared:
15523     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
15524     break;
15525   case OMPC_reduction:
15526     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
15527            "Unexpected lastprivate modifier.");
15528     Res = ActOnOpenMPReductionClause(
15529         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
15530         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
15531         ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
15532     break;
15533   case OMPC_task_reduction:
15534     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15535                                          EndLoc, ReductionOrMapperIdScopeSpec,
15536                                          ReductionOrMapperId);
15537     break;
15538   case OMPC_in_reduction:
15539     Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15540                                        EndLoc, ReductionOrMapperIdScopeSpec,
15541                                        ReductionOrMapperId);
15542     break;
15543   case OMPC_linear:
15544     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
15545            "Unexpected linear modifier.");
15546     Res = ActOnOpenMPLinearClause(
15547         VarList, DepModOrTailExpr, StartLoc, LParenLoc,
15548         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
15549         ColonLoc, EndLoc);
15550     break;
15551   case OMPC_aligned:
15552     Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
15553                                    LParenLoc, ColonLoc, EndLoc);
15554     break;
15555   case OMPC_copyin:
15556     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
15557     break;
15558   case OMPC_copyprivate:
15559     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15560     break;
15561   case OMPC_flush:
15562     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
15563     break;
15564   case OMPC_depend:
15565     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
15566            "Unexpected depend modifier.");
15567     Res = ActOnOpenMPDependClause(
15568         DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
15569         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
15570     break;
15571   case OMPC_map:
15572     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
15573            "Unexpected map modifier.");
15574     Res = ActOnOpenMPMapClause(
15575         MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
15576         ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
15577         IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
15578     break;
15579   case OMPC_to:
15580     Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
15581                               ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
15582                               ColonLoc, VarList, Locs);
15583     break;
15584   case OMPC_from:
15585     Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15586                                 ReductionOrMapperIdScopeSpec,
15587                                 ReductionOrMapperId, ColonLoc, VarList, Locs);
15588     break;
15589   case OMPC_use_device_ptr:
15590     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15591     break;
15592   case OMPC_use_device_addr:
15593     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15594     break;
15595   case OMPC_is_device_ptr:
15596     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15597     break;
15598   case OMPC_allocate:
15599     Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15600                                     LParenLoc, ColonLoc, EndLoc);
15601     break;
15602   case OMPC_nontemporal:
15603     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15604     break;
15605   case OMPC_inclusive:
15606     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15607     break;
15608   case OMPC_exclusive:
15609     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15610     break;
15611   case OMPC_affinity:
15612     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15613                                     DepModOrTailExpr, VarList);
15614     break;
15615   case OMPC_if:
15616   case OMPC_depobj:
15617   case OMPC_final:
15618   case OMPC_num_threads:
15619   case OMPC_safelen:
15620   case OMPC_simdlen:
15621   case OMPC_sizes:
15622   case OMPC_allocator:
15623   case OMPC_collapse:
15624   case OMPC_default:
15625   case OMPC_proc_bind:
15626   case OMPC_schedule:
15627   case OMPC_ordered:
15628   case OMPC_nowait:
15629   case OMPC_untied:
15630   case OMPC_mergeable:
15631   case OMPC_threadprivate:
15632   case OMPC_read:
15633   case OMPC_write:
15634   case OMPC_update:
15635   case OMPC_capture:
15636   case OMPC_seq_cst:
15637   case OMPC_acq_rel:
15638   case OMPC_acquire:
15639   case OMPC_release:
15640   case OMPC_relaxed:
15641   case OMPC_device:
15642   case OMPC_threads:
15643   case OMPC_simd:
15644   case OMPC_num_teams:
15645   case OMPC_thread_limit:
15646   case OMPC_priority:
15647   case OMPC_grainsize:
15648   case OMPC_nogroup:
15649   case OMPC_num_tasks:
15650   case OMPC_hint:
15651   case OMPC_dist_schedule:
15652   case OMPC_defaultmap:
15653   case OMPC_unknown:
15654   case OMPC_uniform:
15655   case OMPC_unified_address:
15656   case OMPC_unified_shared_memory:
15657   case OMPC_reverse_offload:
15658   case OMPC_dynamic_allocators:
15659   case OMPC_atomic_default_mem_order:
15660   case OMPC_device_type:
15661   case OMPC_match:
15662   case OMPC_order:
15663   case OMPC_destroy:
15664   case OMPC_novariants:
15665   case OMPC_nocontext:
15666   case OMPC_detach:
15667   case OMPC_uses_allocators:
15668   case OMPC_when:
15669   default:
15670     llvm_unreachable("Clause is not allowed.");
15671   }
15672   return Res;
15673 }
15674 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)15675 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15676                                        ExprObjectKind OK, SourceLocation Loc) {
15677   ExprResult Res = BuildDeclRefExpr(
15678       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15679   if (!Res.isUsable())
15680     return ExprError();
15681   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15682     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15683     if (!Res.isUsable())
15684       return ExprError();
15685   }
15686   if (VK != VK_LValue && Res.get()->isGLValue()) {
15687     Res = DefaultLvalueConversion(Res.get());
15688     if (!Res.isUsable())
15689       return ExprError();
15690   }
15691   return Res;
15692 }
15693 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15694 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15695                                           SourceLocation StartLoc,
15696                                           SourceLocation LParenLoc,
15697                                           SourceLocation EndLoc) {
15698   SmallVector<Expr *, 8> Vars;
15699   SmallVector<Expr *, 8> PrivateCopies;
15700   for (Expr *RefExpr : VarList) {
15701     assert(RefExpr && "NULL expr in OpenMP private clause.");
15702     SourceLocation ELoc;
15703     SourceRange ERange;
15704     Expr *SimpleRefExpr = RefExpr;
15705     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15706     if (Res.second) {
15707       // It will be analyzed later.
15708       Vars.push_back(RefExpr);
15709       PrivateCopies.push_back(nullptr);
15710     }
15711     ValueDecl *D = Res.first;
15712     if (!D)
15713       continue;
15714 
15715     QualType Type = D->getType();
15716     auto *VD = dyn_cast<VarDecl>(D);
15717 
15718     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15719     //  A variable that appears in a private clause must not have an incomplete
15720     //  type or a reference type.
15721     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15722       continue;
15723     Type = Type.getNonReferenceType();
15724 
15725     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15726     // A variable that is privatized must not have a const-qualified type
15727     // unless it is of class type with a mutable member. This restriction does
15728     // not apply to the firstprivate clause.
15729     //
15730     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15731     // A variable that appears in a private clause must not have a
15732     // const-qualified type unless it is of class type with a mutable member.
15733     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15734       continue;
15735 
15736     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15737     // in a Construct]
15738     //  Variables with the predetermined data-sharing attributes may not be
15739     //  listed in data-sharing attributes clauses, except for the cases
15740     //  listed below. For these exceptions only, listing a predetermined
15741     //  variable in a data-sharing attribute clause is allowed and overrides
15742     //  the variable's predetermined data-sharing attributes.
15743     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15744     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15745       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15746                                           << getOpenMPClauseName(OMPC_private);
15747       reportOriginalDsa(*this, DSAStack, D, DVar);
15748       continue;
15749     }
15750 
15751     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15752     // Variably modified types are not supported for tasks.
15753     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15754         isOpenMPTaskingDirective(CurrDir)) {
15755       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15756           << getOpenMPClauseName(OMPC_private) << Type
15757           << getOpenMPDirectiveName(CurrDir);
15758       bool IsDecl =
15759           !VD ||
15760           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15761       Diag(D->getLocation(),
15762            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15763           << D;
15764       continue;
15765     }
15766 
15767     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15768     // A list item cannot appear in both a map clause and a data-sharing
15769     // attribute clause on the same construct
15770     //
15771     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15772     // A list item cannot appear in both a map clause and a data-sharing
15773     // attribute clause on the same construct unless the construct is a
15774     // combined construct.
15775     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15776         CurrDir == OMPD_target) {
15777       OpenMPClauseKind ConflictKind;
15778       if (DSAStack->checkMappableExprComponentListsForDecl(
15779               VD, /*CurrentRegionOnly=*/true,
15780               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15781                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
15782                 ConflictKind = WhereFoundClauseKind;
15783                 return true;
15784               })) {
15785         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15786             << getOpenMPClauseName(OMPC_private)
15787             << getOpenMPClauseName(ConflictKind)
15788             << getOpenMPDirectiveName(CurrDir);
15789         reportOriginalDsa(*this, DSAStack, D, DVar);
15790         continue;
15791       }
15792     }
15793 
15794     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15795     //  A variable of class type (or array thereof) that appears in a private
15796     //  clause requires an accessible, unambiguous default constructor for the
15797     //  class type.
15798     // Generate helper private variable and initialize it with the default
15799     // value. The address of the original variable is replaced by the address of
15800     // the new private variable in CodeGen. This new variable is not added to
15801     // IdResolver, so the code in the OpenMP region uses original variable for
15802     // proper diagnostics.
15803     Type = Type.getUnqualifiedType();
15804     VarDecl *VDPrivate =
15805         buildVarDecl(*this, ELoc, Type, D->getName(),
15806                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15807                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15808     ActOnUninitializedDecl(VDPrivate);
15809     if (VDPrivate->isInvalidDecl())
15810       continue;
15811     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15812         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15813 
15814     DeclRefExpr *Ref = nullptr;
15815     if (!VD && !CurContext->isDependentContext())
15816       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15817     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15818     Vars.push_back((VD || CurContext->isDependentContext())
15819                        ? RefExpr->IgnoreParens()
15820                        : Ref);
15821     PrivateCopies.push_back(VDPrivateRefExpr);
15822   }
15823 
15824   if (Vars.empty())
15825     return nullptr;
15826 
15827   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15828                                   PrivateCopies);
15829 }
15830 
15831 namespace {
15832 class DiagsUninitializedSeveretyRAII {
15833 private:
15834   DiagnosticsEngine &Diags;
15835   SourceLocation SavedLoc;
15836   bool IsIgnored = false;
15837 
15838 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)15839   DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15840                                  bool IsIgnored)
15841       : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15842     if (!IsIgnored) {
15843       Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15844                         /*Map*/ diag::Severity::Ignored, Loc);
15845     }
15846   }
~DiagsUninitializedSeveretyRAII()15847   ~DiagsUninitializedSeveretyRAII() {
15848     if (!IsIgnored)
15849       Diags.popMappings(SavedLoc);
15850   }
15851 };
15852 }
15853 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15854 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15855                                                SourceLocation StartLoc,
15856                                                SourceLocation LParenLoc,
15857                                                SourceLocation EndLoc) {
15858   SmallVector<Expr *, 8> Vars;
15859   SmallVector<Expr *, 8> PrivateCopies;
15860   SmallVector<Expr *, 8> Inits;
15861   SmallVector<Decl *, 4> ExprCaptures;
15862   bool IsImplicitClause =
15863       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15864   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
15865 
15866   for (Expr *RefExpr : VarList) {
15867     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
15868     SourceLocation ELoc;
15869     SourceRange ERange;
15870     Expr *SimpleRefExpr = RefExpr;
15871     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15872     if (Res.second) {
15873       // It will be analyzed later.
15874       Vars.push_back(RefExpr);
15875       PrivateCopies.push_back(nullptr);
15876       Inits.push_back(nullptr);
15877     }
15878     ValueDecl *D = Res.first;
15879     if (!D)
15880       continue;
15881 
15882     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15883     QualType Type = D->getType();
15884     auto *VD = dyn_cast<VarDecl>(D);
15885 
15886     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15887     //  A variable that appears in a private clause must not have an incomplete
15888     //  type or a reference type.
15889     if (RequireCompleteType(ELoc, Type,
15890                             diag::err_omp_firstprivate_incomplete_type))
15891       continue;
15892     Type = Type.getNonReferenceType();
15893 
15894     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15895     //  A variable of class type (or array thereof) that appears in a private
15896     //  clause requires an accessible, unambiguous copy constructor for the
15897     //  class type.
15898     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15899 
15900     // If an implicit firstprivate variable found it was checked already.
15901     DSAStackTy::DSAVarData TopDVar;
15902     if (!IsImplicitClause) {
15903       DSAStackTy::DSAVarData DVar =
15904           DSAStack->getTopDSA(D, /*FromParent=*/false);
15905       TopDVar = DVar;
15906       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15907       bool IsConstant = ElemType.isConstant(Context);
15908       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15909       //  A list item that specifies a given variable may not appear in more
15910       // than one clause on the same directive, except that a variable may be
15911       //  specified in both firstprivate and lastprivate clauses.
15912       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15913       // A list item may appear in a firstprivate or lastprivate clause but not
15914       // both.
15915       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15916           (isOpenMPDistributeDirective(CurrDir) ||
15917            DVar.CKind != OMPC_lastprivate) &&
15918           DVar.RefExpr) {
15919         Diag(ELoc, diag::err_omp_wrong_dsa)
15920             << getOpenMPClauseName(DVar.CKind)
15921             << getOpenMPClauseName(OMPC_firstprivate);
15922         reportOriginalDsa(*this, DSAStack, D, DVar);
15923         continue;
15924       }
15925 
15926       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15927       // in a Construct]
15928       //  Variables with the predetermined data-sharing attributes may not be
15929       //  listed in data-sharing attributes clauses, except for the cases
15930       //  listed below. For these exceptions only, listing a predetermined
15931       //  variable in a data-sharing attribute clause is allowed and overrides
15932       //  the variable's predetermined data-sharing attributes.
15933       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15934       // in a Construct, C/C++, p.2]
15935       //  Variables with const-qualified type having no mutable member may be
15936       //  listed in a firstprivate clause, even if they are static data members.
15937       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15938           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15939         Diag(ELoc, diag::err_omp_wrong_dsa)
15940             << getOpenMPClauseName(DVar.CKind)
15941             << getOpenMPClauseName(OMPC_firstprivate);
15942         reportOriginalDsa(*this, DSAStack, D, DVar);
15943         continue;
15944       }
15945 
15946       // OpenMP [2.9.3.4, Restrictions, p.2]
15947       //  A list item that is private within a parallel region must not appear
15948       //  in a firstprivate clause on a worksharing construct if any of the
15949       //  worksharing regions arising from the worksharing construct ever bind
15950       //  to any of the parallel regions arising from the parallel construct.
15951       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15952       // A list item that is private within a teams region must not appear in a
15953       // firstprivate clause on a distribute construct if any of the distribute
15954       // regions arising from the distribute construct ever bind to any of the
15955       // teams regions arising from the teams construct.
15956       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15957       // A list item that appears in a reduction clause of a teams construct
15958       // must not appear in a firstprivate clause on a distribute construct if
15959       // any of the distribute regions arising from the distribute construct
15960       // ever bind to any of the teams regions arising from the teams construct.
15961       if ((isOpenMPWorksharingDirective(CurrDir) ||
15962            isOpenMPDistributeDirective(CurrDir)) &&
15963           !isOpenMPParallelDirective(CurrDir) &&
15964           !isOpenMPTeamsDirective(CurrDir)) {
15965         DVar = DSAStack->getImplicitDSA(D, true);
15966         if (DVar.CKind != OMPC_shared &&
15967             (isOpenMPParallelDirective(DVar.DKind) ||
15968              isOpenMPTeamsDirective(DVar.DKind) ||
15969              DVar.DKind == OMPD_unknown)) {
15970           Diag(ELoc, diag::err_omp_required_access)
15971               << getOpenMPClauseName(OMPC_firstprivate)
15972               << getOpenMPClauseName(OMPC_shared);
15973           reportOriginalDsa(*this, DSAStack, D, DVar);
15974           continue;
15975         }
15976       }
15977       // OpenMP [2.9.3.4, Restrictions, p.3]
15978       //  A list item that appears in a reduction clause of a parallel construct
15979       //  must not appear in a firstprivate clause on a worksharing or task
15980       //  construct if any of the worksharing or task regions arising from the
15981       //  worksharing or task construct ever bind to any of the parallel regions
15982       //  arising from the parallel construct.
15983       // OpenMP [2.9.3.4, Restrictions, p.4]
15984       //  A list item that appears in a reduction clause in worksharing
15985       //  construct must not appear in a firstprivate clause in a task construct
15986       //  encountered during execution of any of the worksharing regions arising
15987       //  from the worksharing construct.
15988       if (isOpenMPTaskingDirective(CurrDir)) {
15989         DVar = DSAStack->hasInnermostDSA(
15990             D,
15991             [](OpenMPClauseKind C, bool AppliedToPointee) {
15992               return C == OMPC_reduction && !AppliedToPointee;
15993             },
15994             [](OpenMPDirectiveKind K) {
15995               return isOpenMPParallelDirective(K) ||
15996                      isOpenMPWorksharingDirective(K) ||
15997                      isOpenMPTeamsDirective(K);
15998             },
15999             /*FromParent=*/true);
16000         if (DVar.CKind == OMPC_reduction &&
16001             (isOpenMPParallelDirective(DVar.DKind) ||
16002              isOpenMPWorksharingDirective(DVar.DKind) ||
16003              isOpenMPTeamsDirective(DVar.DKind))) {
16004           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
16005               << getOpenMPDirectiveName(DVar.DKind);
16006           reportOriginalDsa(*this, DSAStack, D, DVar);
16007           continue;
16008         }
16009       }
16010 
16011       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
16012       // A list item cannot appear in both a map clause and a data-sharing
16013       // attribute clause on the same construct
16014       //
16015       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
16016       // A list item cannot appear in both a map clause and a data-sharing
16017       // attribute clause on the same construct unless the construct is a
16018       // combined construct.
16019       if ((LangOpts.OpenMP <= 45 &&
16020            isOpenMPTargetExecutionDirective(CurrDir)) ||
16021           CurrDir == OMPD_target) {
16022         OpenMPClauseKind ConflictKind;
16023         if (DSAStack->checkMappableExprComponentListsForDecl(
16024                 VD, /*CurrentRegionOnly=*/true,
16025                 [&ConflictKind](
16026                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
16027                     OpenMPClauseKind WhereFoundClauseKind) {
16028                   ConflictKind = WhereFoundClauseKind;
16029                   return true;
16030                 })) {
16031           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16032               << getOpenMPClauseName(OMPC_firstprivate)
16033               << getOpenMPClauseName(ConflictKind)
16034               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16035           reportOriginalDsa(*this, DSAStack, D, DVar);
16036           continue;
16037         }
16038       }
16039     }
16040 
16041     // Variably modified types are not supported for tasks.
16042     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
16043         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
16044       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16045           << getOpenMPClauseName(OMPC_firstprivate) << Type
16046           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16047       bool IsDecl =
16048           !VD ||
16049           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16050       Diag(D->getLocation(),
16051            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16052           << D;
16053       continue;
16054     }
16055 
16056     Type = Type.getUnqualifiedType();
16057     VarDecl *VDPrivate =
16058         buildVarDecl(*this, ELoc, Type, D->getName(),
16059                      D->hasAttrs() ? &D->getAttrs() : nullptr,
16060                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16061     // Generate helper private variable and initialize it with the value of the
16062     // original variable. The address of the original variable is replaced by
16063     // the address of the new private variable in the CodeGen. This new variable
16064     // is not added to IdResolver, so the code in the OpenMP region uses
16065     // original variable for proper diagnostics and variable capturing.
16066     Expr *VDInitRefExpr = nullptr;
16067     // For arrays generate initializer for single element and replace it by the
16068     // original array element in CodeGen.
16069     if (Type->isArrayType()) {
16070       VarDecl *VDInit =
16071           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
16072       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
16073       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
16074       ElemType = ElemType.getUnqualifiedType();
16075       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
16076                                          ".firstprivate.temp");
16077       InitializedEntity Entity =
16078           InitializedEntity::InitializeVariable(VDInitTemp);
16079       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
16080 
16081       InitializationSequence InitSeq(*this, Entity, Kind, Init);
16082       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
16083       if (Result.isInvalid())
16084         VDPrivate->setInvalidDecl();
16085       else
16086         VDPrivate->setInit(Result.getAs<Expr>());
16087       // Remove temp variable declaration.
16088       Context.Deallocate(VDInitTemp);
16089     } else {
16090       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
16091                                      ".firstprivate.temp");
16092       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
16093                                        RefExpr->getExprLoc());
16094       AddInitializerToDecl(VDPrivate,
16095                            DefaultLvalueConversion(VDInitRefExpr).get(),
16096                            /*DirectInit=*/false);
16097     }
16098     if (VDPrivate->isInvalidDecl()) {
16099       if (IsImplicitClause) {
16100         Diag(RefExpr->getExprLoc(),
16101              diag::note_omp_task_predetermined_firstprivate_here);
16102       }
16103       continue;
16104     }
16105     CurContext->addDecl(VDPrivate);
16106     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
16107         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
16108         RefExpr->getExprLoc());
16109     DeclRefExpr *Ref = nullptr;
16110     if (!VD && !CurContext->isDependentContext()) {
16111       if (TopDVar.CKind == OMPC_lastprivate) {
16112         Ref = TopDVar.PrivateCopy;
16113       } else {
16114         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16115         if (!isOpenMPCapturedDecl(D))
16116           ExprCaptures.push_back(Ref->getDecl());
16117       }
16118     }
16119     if (!IsImplicitClause)
16120       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
16121     Vars.push_back((VD || CurContext->isDependentContext())
16122                        ? RefExpr->IgnoreParens()
16123                        : Ref);
16124     PrivateCopies.push_back(VDPrivateRefExpr);
16125     Inits.push_back(VDInitRefExpr);
16126   }
16127 
16128   if (Vars.empty())
16129     return nullptr;
16130 
16131   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16132                                        Vars, PrivateCopies, Inits,
16133                                        buildPreInits(Context, ExprCaptures));
16134 }
16135 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16136 OMPClause *Sema::ActOnOpenMPLastprivateClause(
16137     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
16138     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
16139     SourceLocation LParenLoc, SourceLocation EndLoc) {
16140   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
16141     assert(ColonLoc.isValid() && "Colon location must be valid.");
16142     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
16143         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
16144                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
16145         << getOpenMPClauseName(OMPC_lastprivate);
16146     return nullptr;
16147   }
16148 
16149   SmallVector<Expr *, 8> Vars;
16150   SmallVector<Expr *, 8> SrcExprs;
16151   SmallVector<Expr *, 8> DstExprs;
16152   SmallVector<Expr *, 8> AssignmentOps;
16153   SmallVector<Decl *, 4> ExprCaptures;
16154   SmallVector<Expr *, 4> ExprPostUpdates;
16155   for (Expr *RefExpr : VarList) {
16156     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
16157     SourceLocation ELoc;
16158     SourceRange ERange;
16159     Expr *SimpleRefExpr = RefExpr;
16160     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16161     if (Res.second) {
16162       // It will be analyzed later.
16163       Vars.push_back(RefExpr);
16164       SrcExprs.push_back(nullptr);
16165       DstExprs.push_back(nullptr);
16166       AssignmentOps.push_back(nullptr);
16167     }
16168     ValueDecl *D = Res.first;
16169     if (!D)
16170       continue;
16171 
16172     QualType Type = D->getType();
16173     auto *VD = dyn_cast<VarDecl>(D);
16174 
16175     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
16176     //  A variable that appears in a lastprivate clause must not have an
16177     //  incomplete type or a reference type.
16178     if (RequireCompleteType(ELoc, Type,
16179                             diag::err_omp_lastprivate_incomplete_type))
16180       continue;
16181     Type = Type.getNonReferenceType();
16182 
16183     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
16184     // A variable that is privatized must not have a const-qualified type
16185     // unless it is of class type with a mutable member. This restriction does
16186     // not apply to the firstprivate clause.
16187     //
16188     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
16189     // A variable that appears in a lastprivate clause must not have a
16190     // const-qualified type unless it is of class type with a mutable member.
16191     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
16192       continue;
16193 
16194     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
16195     // A list item that appears in a lastprivate clause with the conditional
16196     // modifier must be a scalar variable.
16197     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
16198       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
16199       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16200                                VarDecl::DeclarationOnly;
16201       Diag(D->getLocation(),
16202            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16203           << D;
16204       continue;
16205     }
16206 
16207     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
16208     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16209     // in a Construct]
16210     //  Variables with the predetermined data-sharing attributes may not be
16211     //  listed in data-sharing attributes clauses, except for the cases
16212     //  listed below.
16213     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
16214     // A list item may appear in a firstprivate or lastprivate clause but not
16215     // both.
16216     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
16217     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
16218         (isOpenMPDistributeDirective(CurrDir) ||
16219          DVar.CKind != OMPC_firstprivate) &&
16220         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
16221       Diag(ELoc, diag::err_omp_wrong_dsa)
16222           << getOpenMPClauseName(DVar.CKind)
16223           << getOpenMPClauseName(OMPC_lastprivate);
16224       reportOriginalDsa(*this, DSAStack, D, DVar);
16225       continue;
16226     }
16227 
16228     // OpenMP [2.14.3.5, Restrictions, p.2]
16229     // A list item that is private within a parallel region, or that appears in
16230     // the reduction clause of a parallel construct, must not appear in a
16231     // lastprivate clause on a worksharing construct if any of the corresponding
16232     // worksharing regions ever binds to any of the corresponding parallel
16233     // regions.
16234     DSAStackTy::DSAVarData TopDVar = DVar;
16235     if (isOpenMPWorksharingDirective(CurrDir) &&
16236         !isOpenMPParallelDirective(CurrDir) &&
16237         !isOpenMPTeamsDirective(CurrDir)) {
16238       DVar = DSAStack->getImplicitDSA(D, true);
16239       if (DVar.CKind != OMPC_shared) {
16240         Diag(ELoc, diag::err_omp_required_access)
16241             << getOpenMPClauseName(OMPC_lastprivate)
16242             << getOpenMPClauseName(OMPC_shared);
16243         reportOriginalDsa(*this, DSAStack, D, DVar);
16244         continue;
16245       }
16246     }
16247 
16248     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
16249     //  A variable of class type (or array thereof) that appears in a
16250     //  lastprivate clause requires an accessible, unambiguous default
16251     //  constructor for the class type, unless the list item is also specified
16252     //  in a firstprivate clause.
16253     //  A variable of class type (or array thereof) that appears in a
16254     //  lastprivate clause requires an accessible, unambiguous copy assignment
16255     //  operator for the class type.
16256     Type = Context.getBaseElementType(Type).getNonReferenceType();
16257     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
16258                                   Type.getUnqualifiedType(), ".lastprivate.src",
16259                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
16260     DeclRefExpr *PseudoSrcExpr =
16261         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
16262     VarDecl *DstVD =
16263         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
16264                      D->hasAttrs() ? &D->getAttrs() : nullptr);
16265     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16266     // For arrays generate assignment operation for single element and replace
16267     // it by the original array element in CodeGen.
16268     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
16269                                          PseudoDstExpr, PseudoSrcExpr);
16270     if (AssignmentOp.isInvalid())
16271       continue;
16272     AssignmentOp =
16273         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16274     if (AssignmentOp.isInvalid())
16275       continue;
16276 
16277     DeclRefExpr *Ref = nullptr;
16278     if (!VD && !CurContext->isDependentContext()) {
16279       if (TopDVar.CKind == OMPC_firstprivate) {
16280         Ref = TopDVar.PrivateCopy;
16281       } else {
16282         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16283         if (!isOpenMPCapturedDecl(D))
16284           ExprCaptures.push_back(Ref->getDecl());
16285       }
16286       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
16287           (!isOpenMPCapturedDecl(D) &&
16288            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
16289         ExprResult RefRes = DefaultLvalueConversion(Ref);
16290         if (!RefRes.isUsable())
16291           continue;
16292         ExprResult PostUpdateRes =
16293             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
16294                        RefRes.get());
16295         if (!PostUpdateRes.isUsable())
16296           continue;
16297         ExprPostUpdates.push_back(
16298             IgnoredValueConversions(PostUpdateRes.get()).get());
16299       }
16300     }
16301     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
16302     Vars.push_back((VD || CurContext->isDependentContext())
16303                        ? RefExpr->IgnoreParens()
16304                        : Ref);
16305     SrcExprs.push_back(PseudoSrcExpr);
16306     DstExprs.push_back(PseudoDstExpr);
16307     AssignmentOps.push_back(AssignmentOp.get());
16308   }
16309 
16310   if (Vars.empty())
16311     return nullptr;
16312 
16313   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16314                                       Vars, SrcExprs, DstExprs, AssignmentOps,
16315                                       LPKind, LPKindLoc, ColonLoc,
16316                                       buildPreInits(Context, ExprCaptures),
16317                                       buildPostUpdate(*this, ExprPostUpdates));
16318 }
16319 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16320 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
16321                                          SourceLocation StartLoc,
16322                                          SourceLocation LParenLoc,
16323                                          SourceLocation EndLoc) {
16324   SmallVector<Expr *, 8> Vars;
16325   for (Expr *RefExpr : VarList) {
16326     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
16327     SourceLocation ELoc;
16328     SourceRange ERange;
16329     Expr *SimpleRefExpr = RefExpr;
16330     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16331     if (Res.second) {
16332       // It will be analyzed later.
16333       Vars.push_back(RefExpr);
16334     }
16335     ValueDecl *D = Res.first;
16336     if (!D)
16337       continue;
16338 
16339     auto *VD = dyn_cast<VarDecl>(D);
16340     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
16341     // in a Construct]
16342     //  Variables with the predetermined data-sharing attributes may not be
16343     //  listed in data-sharing attributes clauses, except for the cases
16344     //  listed below. For these exceptions only, listing a predetermined
16345     //  variable in a data-sharing attribute clause is allowed and overrides
16346     //  the variable's predetermined data-sharing attributes.
16347     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
16348     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
16349         DVar.RefExpr) {
16350       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
16351                                           << getOpenMPClauseName(OMPC_shared);
16352       reportOriginalDsa(*this, DSAStack, D, DVar);
16353       continue;
16354     }
16355 
16356     DeclRefExpr *Ref = nullptr;
16357     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
16358       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16359     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
16360     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
16361                        ? RefExpr->IgnoreParens()
16362                        : Ref);
16363   }
16364 
16365   if (Vars.empty())
16366     return nullptr;
16367 
16368   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
16369 }
16370 
16371 namespace {
16372 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
16373   DSAStackTy *Stack;
16374 
16375 public:
VisitDeclRefExpr(DeclRefExpr * E)16376   bool VisitDeclRefExpr(DeclRefExpr *E) {
16377     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
16378       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
16379       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
16380         return false;
16381       if (DVar.CKind != OMPC_unknown)
16382         return true;
16383       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
16384           VD,
16385           [](OpenMPClauseKind C, bool AppliedToPointee) {
16386             return isOpenMPPrivate(C) && !AppliedToPointee;
16387           },
16388           [](OpenMPDirectiveKind) { return true; },
16389           /*FromParent=*/true);
16390       return DVarPrivate.CKind != OMPC_unknown;
16391     }
16392     return false;
16393   }
VisitStmt(Stmt * S)16394   bool VisitStmt(Stmt *S) {
16395     for (Stmt *Child : S->children()) {
16396       if (Child && Visit(Child))
16397         return true;
16398     }
16399     return false;
16400   }
DSARefChecker(DSAStackTy * S)16401   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
16402 };
16403 } // namespace
16404 
16405 namespace {
16406 // Transform MemberExpression for specified FieldDecl of current class to
16407 // DeclRefExpr to specified OMPCapturedExprDecl.
16408 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
16409   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
16410   ValueDecl *Field = nullptr;
16411   DeclRefExpr *CapturedExpr = nullptr;
16412 
16413 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)16414   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
16415       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
16416 
TransformMemberExpr(MemberExpr * E)16417   ExprResult TransformMemberExpr(MemberExpr *E) {
16418     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
16419         E->getMemberDecl() == Field) {
16420       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
16421       return CapturedExpr;
16422     }
16423     return BaseTransform::TransformMemberExpr(E);
16424   }
getCapturedExpr()16425   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
16426 };
16427 } // namespace
16428 
16429 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)16430 static T filterLookupForUDReductionAndMapper(
16431     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
16432   for (U &Set : Lookups) {
16433     for (auto *D : Set) {
16434       if (T Res = Gen(cast<ValueDecl>(D)))
16435         return Res;
16436     }
16437   }
16438   return T();
16439 }
16440 
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)16441 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
16442   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
16443 
16444   for (auto RD : D->redecls()) {
16445     // Don't bother with extra checks if we already know this one isn't visible.
16446     if (RD == D)
16447       continue;
16448 
16449     auto ND = cast<NamedDecl>(RD);
16450     if (LookupResult::isVisible(SemaRef, ND))
16451       return ND;
16452   }
16453 
16454   return nullptr;
16455 }
16456 
16457 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)16458 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
16459                         SourceLocation Loc, QualType Ty,
16460                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
16461   // Find all of the associated namespaces and classes based on the
16462   // arguments we have.
16463   Sema::AssociatedNamespaceSet AssociatedNamespaces;
16464   Sema::AssociatedClassSet AssociatedClasses;
16465   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
16466   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
16467                                              AssociatedClasses);
16468 
16469   // C++ [basic.lookup.argdep]p3:
16470   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
16471   //   and let Y be the lookup set produced by argument dependent
16472   //   lookup (defined as follows). If X contains [...] then Y is
16473   //   empty. Otherwise Y is the set of declarations found in the
16474   //   namespaces associated with the argument types as described
16475   //   below. The set of declarations found by the lookup of the name
16476   //   is the union of X and Y.
16477   //
16478   // Here, we compute Y and add its members to the overloaded
16479   // candidate set.
16480   for (auto *NS : AssociatedNamespaces) {
16481     //   When considering an associated namespace, the lookup is the
16482     //   same as the lookup performed when the associated namespace is
16483     //   used as a qualifier (3.4.3.2) except that:
16484     //
16485     //     -- Any using-directives in the associated namespace are
16486     //        ignored.
16487     //
16488     //     -- Any namespace-scope friend functions declared in
16489     //        associated classes are visible within their respective
16490     //        namespaces even if they are not visible during an ordinary
16491     //        lookup (11.4).
16492     DeclContext::lookup_result R = NS->lookup(Id.getName());
16493     for (auto *D : R) {
16494       auto *Underlying = D;
16495       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16496         Underlying = USD->getTargetDecl();
16497 
16498       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
16499           !isa<OMPDeclareMapperDecl>(Underlying))
16500         continue;
16501 
16502       if (!SemaRef.isVisible(D)) {
16503         D = findAcceptableDecl(SemaRef, D);
16504         if (!D)
16505           continue;
16506         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16507           Underlying = USD->getTargetDecl();
16508       }
16509       Lookups.emplace_back();
16510       Lookups.back().addDecl(Underlying);
16511     }
16512   }
16513 }
16514 
16515 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)16516 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
16517                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
16518                          const DeclarationNameInfo &ReductionId, QualType Ty,
16519                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
16520   if (ReductionIdScopeSpec.isInvalid())
16521     return ExprError();
16522   SmallVector<UnresolvedSet<8>, 4> Lookups;
16523   if (S) {
16524     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16525     Lookup.suppressDiagnostics();
16526     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
16527       NamedDecl *D = Lookup.getRepresentativeDecl();
16528       do {
16529         S = S->getParent();
16530       } while (S && !S->isDeclScope(D));
16531       if (S)
16532         S = S->getParent();
16533       Lookups.emplace_back();
16534       Lookups.back().append(Lookup.begin(), Lookup.end());
16535       Lookup.clear();
16536     }
16537   } else if (auto *ULE =
16538                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
16539     Lookups.push_back(UnresolvedSet<8>());
16540     Decl *PrevD = nullptr;
16541     for (NamedDecl *D : ULE->decls()) {
16542       if (D == PrevD)
16543         Lookups.push_back(UnresolvedSet<8>());
16544       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
16545         Lookups.back().addDecl(DRD);
16546       PrevD = D;
16547     }
16548   }
16549   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
16550       Ty->isInstantiationDependentType() ||
16551       Ty->containsUnexpandedParameterPack() ||
16552       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16553         return !D->isInvalidDecl() &&
16554                (D->getType()->isDependentType() ||
16555                 D->getType()->isInstantiationDependentType() ||
16556                 D->getType()->containsUnexpandedParameterPack());
16557       })) {
16558     UnresolvedSet<8> ResSet;
16559     for (const UnresolvedSet<8> &Set : Lookups) {
16560       if (Set.empty())
16561         continue;
16562       ResSet.append(Set.begin(), Set.end());
16563       // The last item marks the end of all declarations at the specified scope.
16564       ResSet.addDecl(Set[Set.size() - 1]);
16565     }
16566     return UnresolvedLookupExpr::Create(
16567         SemaRef.Context, /*NamingClass=*/nullptr,
16568         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
16569         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
16570   }
16571   // Lookup inside the classes.
16572   // C++ [over.match.oper]p3:
16573   //   For a unary operator @ with an operand of a type whose
16574   //   cv-unqualified version is T1, and for a binary operator @ with
16575   //   a left operand of a type whose cv-unqualified version is T1 and
16576   //   a right operand of a type whose cv-unqualified version is T2,
16577   //   three sets of candidate functions, designated member
16578   //   candidates, non-member candidates and built-in candidates, are
16579   //   constructed as follows:
16580   //     -- If T1 is a complete class type or a class currently being
16581   //        defined, the set of member candidates is the result of the
16582   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
16583   //        the set of member candidates is empty.
16584   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16585   Lookup.suppressDiagnostics();
16586   if (const auto *TyRec = Ty->getAs<RecordType>()) {
16587     // Complete the type if it can be completed.
16588     // If the type is neither complete nor being defined, bail out now.
16589     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16590         TyRec->getDecl()->getDefinition()) {
16591       Lookup.clear();
16592       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16593       if (Lookup.empty()) {
16594         Lookups.emplace_back();
16595         Lookups.back().append(Lookup.begin(), Lookup.end());
16596       }
16597     }
16598   }
16599   // Perform ADL.
16600   if (SemaRef.getLangOpts().CPlusPlus)
16601     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16602   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16603           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16604             if (!D->isInvalidDecl() &&
16605                 SemaRef.Context.hasSameType(D->getType(), Ty))
16606               return D;
16607             return nullptr;
16608           }))
16609     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16610                                     VK_LValue, Loc);
16611   if (SemaRef.getLangOpts().CPlusPlus) {
16612     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16613             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16614               if (!D->isInvalidDecl() &&
16615                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16616                   !Ty.isMoreQualifiedThan(D->getType()))
16617                 return D;
16618               return nullptr;
16619             })) {
16620       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16621                          /*DetectVirtual=*/false);
16622       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16623         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16624                 VD->getType().getUnqualifiedType()))) {
16625           if (SemaRef.CheckBaseClassAccess(
16626                   Loc, VD->getType(), Ty, Paths.front(),
16627                   /*DiagID=*/0) != Sema::AR_inaccessible) {
16628             SemaRef.BuildBasePathArray(Paths, BasePath);
16629             return SemaRef.BuildDeclRefExpr(
16630                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16631           }
16632         }
16633       }
16634     }
16635   }
16636   if (ReductionIdScopeSpec.isSet()) {
16637     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16638         << Ty << Range;
16639     return ExprError();
16640   }
16641   return ExprEmpty();
16642 }
16643 
16644 namespace {
16645 /// Data for the reduction-based clauses.
16646 struct ReductionData {
16647   /// List of original reduction items.
16648   SmallVector<Expr *, 8> Vars;
16649   /// List of private copies of the reduction items.
16650   SmallVector<Expr *, 8> Privates;
16651   /// LHS expressions for the reduction_op expressions.
16652   SmallVector<Expr *, 8> LHSs;
16653   /// RHS expressions for the reduction_op expressions.
16654   SmallVector<Expr *, 8> RHSs;
16655   /// Reduction operation expression.
16656   SmallVector<Expr *, 8> ReductionOps;
16657   /// inscan copy operation expressions.
16658   SmallVector<Expr *, 8> InscanCopyOps;
16659   /// inscan copy temp array expressions for prefix sums.
16660   SmallVector<Expr *, 8> InscanCopyArrayTemps;
16661   /// inscan copy temp array element expressions for prefix sums.
16662   SmallVector<Expr *, 8> InscanCopyArrayElems;
16663   /// Taskgroup descriptors for the corresponding reduction items in
16664   /// in_reduction clauses.
16665   SmallVector<Expr *, 8> TaskgroupDescriptors;
16666   /// List of captures for clause.
16667   SmallVector<Decl *, 4> ExprCaptures;
16668   /// List of postupdate expressions.
16669   SmallVector<Expr *, 4> ExprPostUpdates;
16670   /// Reduction modifier.
16671   unsigned RedModifier = 0;
16672   ReductionData() = delete;
16673   /// Reserves required memory for the reduction data.
ReductionData__anon850ef1bd5311::ReductionData16674   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16675     Vars.reserve(Size);
16676     Privates.reserve(Size);
16677     LHSs.reserve(Size);
16678     RHSs.reserve(Size);
16679     ReductionOps.reserve(Size);
16680     if (RedModifier == OMPC_REDUCTION_inscan) {
16681       InscanCopyOps.reserve(Size);
16682       InscanCopyArrayTemps.reserve(Size);
16683       InscanCopyArrayElems.reserve(Size);
16684     }
16685     TaskgroupDescriptors.reserve(Size);
16686     ExprCaptures.reserve(Size);
16687     ExprPostUpdates.reserve(Size);
16688   }
16689   /// Stores reduction item and reduction operation only (required for dependent
16690   /// reduction item).
push__anon850ef1bd5311::ReductionData16691   void push(Expr *Item, Expr *ReductionOp) {
16692     Vars.emplace_back(Item);
16693     Privates.emplace_back(nullptr);
16694     LHSs.emplace_back(nullptr);
16695     RHSs.emplace_back(nullptr);
16696     ReductionOps.emplace_back(ReductionOp);
16697     TaskgroupDescriptors.emplace_back(nullptr);
16698     if (RedModifier == OMPC_REDUCTION_inscan) {
16699       InscanCopyOps.push_back(nullptr);
16700       InscanCopyArrayTemps.push_back(nullptr);
16701       InscanCopyArrayElems.push_back(nullptr);
16702     }
16703   }
16704   /// Stores reduction data.
push__anon850ef1bd5311::ReductionData16705   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16706             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16707             Expr *CopyArrayElem) {
16708     Vars.emplace_back(Item);
16709     Privates.emplace_back(Private);
16710     LHSs.emplace_back(LHS);
16711     RHSs.emplace_back(RHS);
16712     ReductionOps.emplace_back(ReductionOp);
16713     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16714     if (RedModifier == OMPC_REDUCTION_inscan) {
16715       InscanCopyOps.push_back(CopyOp);
16716       InscanCopyArrayTemps.push_back(CopyArrayTemp);
16717       InscanCopyArrayElems.push_back(CopyArrayElem);
16718     } else {
16719       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
16720              CopyArrayElem == nullptr &&
16721              "Copy operation must be used for inscan reductions only.");
16722     }
16723   }
16724 };
16725 } // namespace
16726 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)16727 static bool checkOMPArraySectionConstantForReduction(
16728     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16729     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16730   const Expr *Length = OASE->getLength();
16731   if (Length == nullptr) {
16732     // For array sections of the form [1:] or [:], we would need to analyze
16733     // the lower bound...
16734     if (OASE->getColonLocFirst().isValid())
16735       return false;
16736 
16737     // This is an array subscript which has implicit length 1!
16738     SingleElement = true;
16739     ArraySizes.push_back(llvm::APSInt::get(1));
16740   } else {
16741     Expr::EvalResult Result;
16742     if (!Length->EvaluateAsInt(Result, Context))
16743       return false;
16744 
16745     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16746     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16747     ArraySizes.push_back(ConstantLengthValue);
16748   }
16749 
16750   // Get the base of this array section and walk up from there.
16751   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16752 
16753   // We require length = 1 for all array sections except the right-most to
16754   // guarantee that the memory region is contiguous and has no holes in it.
16755   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16756     Length = TempOASE->getLength();
16757     if (Length == nullptr) {
16758       // For array sections of the form [1:] or [:], we would need to analyze
16759       // the lower bound...
16760       if (OASE->getColonLocFirst().isValid())
16761         return false;
16762 
16763       // This is an array subscript which has implicit length 1!
16764       ArraySizes.push_back(llvm::APSInt::get(1));
16765     } else {
16766       Expr::EvalResult Result;
16767       if (!Length->EvaluateAsInt(Result, Context))
16768         return false;
16769 
16770       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16771       if (ConstantLengthValue.getSExtValue() != 1)
16772         return false;
16773 
16774       ArraySizes.push_back(ConstantLengthValue);
16775     }
16776     Base = TempOASE->getBase()->IgnoreParenImpCasts();
16777   }
16778 
16779   // If we have a single element, we don't need to add the implicit lengths.
16780   if (!SingleElement) {
16781     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16782       // Has implicit length 1!
16783       ArraySizes.push_back(llvm::APSInt::get(1));
16784       Base = TempASE->getBase()->IgnoreParenImpCasts();
16785     }
16786   }
16787 
16788   // This array section can be privatized as a single value or as a constant
16789   // sized array.
16790   return true;
16791 }
16792 
16793 static BinaryOperatorKind
getRelatedCompoundReductionOp(BinaryOperatorKind BOK)16794 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
16795   if (BOK == BO_Add)
16796     return BO_AddAssign;
16797   if (BOK == BO_Mul)
16798     return BO_MulAssign;
16799   if (BOK == BO_And)
16800     return BO_AndAssign;
16801   if (BOK == BO_Or)
16802     return BO_OrAssign;
16803   if (BOK == BO_Xor)
16804     return BO_XorAssign;
16805   return BOK;
16806 }
16807 
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)16808 static bool actOnOMPReductionKindClause(
16809     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16810     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16811     SourceLocation ColonLoc, SourceLocation EndLoc,
16812     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16813     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16814   DeclarationName DN = ReductionId.getName();
16815   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16816   BinaryOperatorKind BOK = BO_Comma;
16817 
16818   ASTContext &Context = S.Context;
16819   // OpenMP [2.14.3.6, reduction clause]
16820   // C
16821   // reduction-identifier is either an identifier or one of the following
16822   // operators: +, -, *,  &, |, ^, && and ||
16823   // C++
16824   // reduction-identifier is either an id-expression or one of the following
16825   // operators: +, -, *, &, |, ^, && and ||
16826   switch (OOK) {
16827   case OO_Plus:
16828   case OO_Minus:
16829     BOK = BO_Add;
16830     break;
16831   case OO_Star:
16832     BOK = BO_Mul;
16833     break;
16834   case OO_Amp:
16835     BOK = BO_And;
16836     break;
16837   case OO_Pipe:
16838     BOK = BO_Or;
16839     break;
16840   case OO_Caret:
16841     BOK = BO_Xor;
16842     break;
16843   case OO_AmpAmp:
16844     BOK = BO_LAnd;
16845     break;
16846   case OO_PipePipe:
16847     BOK = BO_LOr;
16848     break;
16849   case OO_New:
16850   case OO_Delete:
16851   case OO_Array_New:
16852   case OO_Array_Delete:
16853   case OO_Slash:
16854   case OO_Percent:
16855   case OO_Tilde:
16856   case OO_Exclaim:
16857   case OO_Equal:
16858   case OO_Less:
16859   case OO_Greater:
16860   case OO_LessEqual:
16861   case OO_GreaterEqual:
16862   case OO_PlusEqual:
16863   case OO_MinusEqual:
16864   case OO_StarEqual:
16865   case OO_SlashEqual:
16866   case OO_PercentEqual:
16867   case OO_CaretEqual:
16868   case OO_AmpEqual:
16869   case OO_PipeEqual:
16870   case OO_LessLess:
16871   case OO_GreaterGreater:
16872   case OO_LessLessEqual:
16873   case OO_GreaterGreaterEqual:
16874   case OO_EqualEqual:
16875   case OO_ExclaimEqual:
16876   case OO_Spaceship:
16877   case OO_PlusPlus:
16878   case OO_MinusMinus:
16879   case OO_Comma:
16880   case OO_ArrowStar:
16881   case OO_Arrow:
16882   case OO_Call:
16883   case OO_Subscript:
16884   case OO_Conditional:
16885   case OO_Coawait:
16886   case NUM_OVERLOADED_OPERATORS:
16887     llvm_unreachable("Unexpected reduction identifier");
16888   case OO_None:
16889     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16890       if (II->isStr("max"))
16891         BOK = BO_GT;
16892       else if (II->isStr("min"))
16893         BOK = BO_LT;
16894     }
16895     break;
16896   }
16897   SourceRange ReductionIdRange;
16898   if (ReductionIdScopeSpec.isValid())
16899     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16900   else
16901     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16902   ReductionIdRange.setEnd(ReductionId.getEndLoc());
16903 
16904   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16905   bool FirstIter = true;
16906   for (Expr *RefExpr : VarList) {
16907     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
16908     // OpenMP [2.1, C/C++]
16909     //  A list item is a variable or array section, subject to the restrictions
16910     //  specified in Section 2.4 on page 42 and in each of the sections
16911     // describing clauses and directives for which a list appears.
16912     // OpenMP  [2.14.3.3, Restrictions, p.1]
16913     //  A variable that is part of another variable (as an array or
16914     //  structure element) cannot appear in a private clause.
16915     if (!FirstIter && IR != ER)
16916       ++IR;
16917     FirstIter = false;
16918     SourceLocation ELoc;
16919     SourceRange ERange;
16920     Expr *SimpleRefExpr = RefExpr;
16921     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16922                               /*AllowArraySection=*/true);
16923     if (Res.second) {
16924       // Try to find 'declare reduction' corresponding construct before using
16925       // builtin/overloaded operators.
16926       QualType Type = Context.DependentTy;
16927       CXXCastPath BasePath;
16928       ExprResult DeclareReductionRef = buildDeclareReductionRef(
16929           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16930           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16931       Expr *ReductionOp = nullptr;
16932       if (S.CurContext->isDependentContext() &&
16933           (DeclareReductionRef.isUnset() ||
16934            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16935         ReductionOp = DeclareReductionRef.get();
16936       // It will be analyzed later.
16937       RD.push(RefExpr, ReductionOp);
16938     }
16939     ValueDecl *D = Res.first;
16940     if (!D)
16941       continue;
16942 
16943     Expr *TaskgroupDescriptor = nullptr;
16944     QualType Type;
16945     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16946     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16947     if (ASE) {
16948       Type = ASE->getType().getNonReferenceType();
16949     } else if (OASE) {
16950       QualType BaseType =
16951           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16952       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16953         Type = ATy->getElementType();
16954       else
16955         Type = BaseType->getPointeeType();
16956       Type = Type.getNonReferenceType();
16957     } else {
16958       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16959     }
16960     auto *VD = dyn_cast<VarDecl>(D);
16961 
16962     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16963     //  A variable that appears in a private clause must not have an incomplete
16964     //  type or a reference type.
16965     if (S.RequireCompleteType(ELoc, D->getType(),
16966                               diag::err_omp_reduction_incomplete_type))
16967       continue;
16968     // OpenMP [2.14.3.6, reduction clause, Restrictions]
16969     // A list item that appears in a reduction clause must not be
16970     // const-qualified.
16971     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16972                                   /*AcceptIfMutable*/ false, ASE || OASE))
16973       continue;
16974 
16975     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16976     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16977     //  If a list-item is a reference type then it must bind to the same object
16978     //  for all threads of the team.
16979     if (!ASE && !OASE) {
16980       if (VD) {
16981         VarDecl *VDDef = VD->getDefinition();
16982         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16983           DSARefChecker Check(Stack);
16984           if (Check.Visit(VDDef->getInit())) {
16985             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16986                 << getOpenMPClauseName(ClauseKind) << ERange;
16987             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16988             continue;
16989           }
16990         }
16991       }
16992 
16993       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16994       // in a Construct]
16995       //  Variables with the predetermined data-sharing attributes may not be
16996       //  listed in data-sharing attributes clauses, except for the cases
16997       //  listed below. For these exceptions only, listing a predetermined
16998       //  variable in a data-sharing attribute clause is allowed and overrides
16999       //  the variable's predetermined data-sharing attributes.
17000       // OpenMP [2.14.3.6, Restrictions, p.3]
17001       //  Any number of reduction clauses can be specified on the directive,
17002       //  but a list item can appear only once in the reduction clauses for that
17003       //  directive.
17004       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
17005       if (DVar.CKind == OMPC_reduction) {
17006         S.Diag(ELoc, diag::err_omp_once_referenced)
17007             << getOpenMPClauseName(ClauseKind);
17008         if (DVar.RefExpr)
17009           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
17010         continue;
17011       }
17012       if (DVar.CKind != OMPC_unknown) {
17013         S.Diag(ELoc, diag::err_omp_wrong_dsa)
17014             << getOpenMPClauseName(DVar.CKind)
17015             << getOpenMPClauseName(OMPC_reduction);
17016         reportOriginalDsa(S, Stack, D, DVar);
17017         continue;
17018       }
17019 
17020       // OpenMP [2.14.3.6, Restrictions, p.1]
17021       //  A list item that appears in a reduction clause of a worksharing
17022       //  construct must be shared in the parallel regions to which any of the
17023       //  worksharing regions arising from the worksharing construct bind.
17024       if (isOpenMPWorksharingDirective(CurrDir) &&
17025           !isOpenMPParallelDirective(CurrDir) &&
17026           !isOpenMPTeamsDirective(CurrDir)) {
17027         DVar = Stack->getImplicitDSA(D, true);
17028         if (DVar.CKind != OMPC_shared) {
17029           S.Diag(ELoc, diag::err_omp_required_access)
17030               << getOpenMPClauseName(OMPC_reduction)
17031               << getOpenMPClauseName(OMPC_shared);
17032           reportOriginalDsa(S, Stack, D, DVar);
17033           continue;
17034         }
17035       }
17036     } else {
17037       // Threadprivates cannot be shared between threads, so dignose if the base
17038       // is a threadprivate variable.
17039       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
17040       if (DVar.CKind == OMPC_threadprivate) {
17041         S.Diag(ELoc, diag::err_omp_wrong_dsa)
17042             << getOpenMPClauseName(DVar.CKind)
17043             << getOpenMPClauseName(OMPC_reduction);
17044         reportOriginalDsa(S, Stack, D, DVar);
17045         continue;
17046       }
17047     }
17048 
17049     // Try to find 'declare reduction' corresponding construct before using
17050     // builtin/overloaded operators.
17051     CXXCastPath BasePath;
17052     ExprResult DeclareReductionRef = buildDeclareReductionRef(
17053         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
17054         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
17055     if (DeclareReductionRef.isInvalid())
17056       continue;
17057     if (S.CurContext->isDependentContext() &&
17058         (DeclareReductionRef.isUnset() ||
17059          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
17060       RD.push(RefExpr, DeclareReductionRef.get());
17061       continue;
17062     }
17063     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
17064       // Not allowed reduction identifier is found.
17065       S.Diag(ReductionId.getBeginLoc(),
17066              diag::err_omp_unknown_reduction_identifier)
17067           << Type << ReductionIdRange;
17068       continue;
17069     }
17070 
17071     // OpenMP [2.14.3.6, reduction clause, Restrictions]
17072     // The type of a list item that appears in a reduction clause must be valid
17073     // for the reduction-identifier. For a max or min reduction in C, the type
17074     // of the list item must be an allowed arithmetic data type: char, int,
17075     // float, double, or _Bool, possibly modified with long, short, signed, or
17076     // unsigned. For a max or min reduction in C++, the type of the list item
17077     // must be an allowed arithmetic data type: char, wchar_t, int, float,
17078     // double, or bool, possibly modified with long, short, signed, or unsigned.
17079     if (DeclareReductionRef.isUnset()) {
17080       if ((BOK == BO_GT || BOK == BO_LT) &&
17081           !(Type->isScalarType() ||
17082             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
17083         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
17084             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
17085         if (!ASE && !OASE) {
17086           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17087                                    VarDecl::DeclarationOnly;
17088           S.Diag(D->getLocation(),
17089                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17090               << D;
17091         }
17092         continue;
17093       }
17094       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
17095           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
17096         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
17097             << getOpenMPClauseName(ClauseKind);
17098         if (!ASE && !OASE) {
17099           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17100                                    VarDecl::DeclarationOnly;
17101           S.Diag(D->getLocation(),
17102                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17103               << D;
17104         }
17105         continue;
17106       }
17107     }
17108 
17109     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
17110     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
17111                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
17112     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
17113                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
17114     QualType PrivateTy = Type;
17115 
17116     // Try if we can determine constant lengths for all array sections and avoid
17117     // the VLA.
17118     bool ConstantLengthOASE = false;
17119     if (OASE) {
17120       bool SingleElement;
17121       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
17122       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
17123           Context, OASE, SingleElement, ArraySizes);
17124 
17125       // If we don't have a single element, we must emit a constant array type.
17126       if (ConstantLengthOASE && !SingleElement) {
17127         for (llvm::APSInt &Size : ArraySizes)
17128           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
17129                                                    ArrayType::Normal,
17130                                                    /*IndexTypeQuals=*/0);
17131       }
17132     }
17133 
17134     if ((OASE && !ConstantLengthOASE) ||
17135         (!OASE && !ASE &&
17136          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
17137       if (!Context.getTargetInfo().isVLASupported()) {
17138         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
17139           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17140           S.Diag(ELoc, diag::note_vla_unsupported);
17141           continue;
17142         } else {
17143           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17144           S.targetDiag(ELoc, diag::note_vla_unsupported);
17145         }
17146       }
17147       // For arrays/array sections only:
17148       // Create pseudo array type for private copy. The size for this array will
17149       // be generated during codegen.
17150       // For array subscripts or single variables Private Ty is the same as Type
17151       // (type of the variable or single array element).
17152       PrivateTy = Context.getVariableArrayType(
17153           Type,
17154           new (Context)
17155               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
17156           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
17157     } else if (!ASE && !OASE &&
17158                Context.getAsArrayType(D->getType().getNonReferenceType())) {
17159       PrivateTy = D->getType().getNonReferenceType();
17160     }
17161     // Private copy.
17162     VarDecl *PrivateVD =
17163         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17164                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17165                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17166     // Add initializer for private variable.
17167     Expr *Init = nullptr;
17168     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
17169     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
17170     if (DeclareReductionRef.isUsable()) {
17171       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
17172       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
17173       if (DRD->getInitializer()) {
17174         Init = DRDRef;
17175         RHSVD->setInit(DRDRef);
17176         RHSVD->setInitStyle(VarDecl::CallInit);
17177       }
17178     } else {
17179       switch (BOK) {
17180       case BO_Add:
17181       case BO_Xor:
17182       case BO_Or:
17183       case BO_LOr:
17184         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
17185         if (Type->isScalarType() || Type->isAnyComplexType())
17186           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
17187         break;
17188       case BO_Mul:
17189       case BO_LAnd:
17190         if (Type->isScalarType() || Type->isAnyComplexType()) {
17191           // '*' and '&&' reduction ops - initializer is '1'.
17192           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
17193         }
17194         break;
17195       case BO_And: {
17196         // '&' reduction op - initializer is '~0'.
17197         QualType OrigType = Type;
17198         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
17199           Type = ComplexTy->getElementType();
17200         if (Type->isRealFloatingType()) {
17201           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
17202               Context.getFloatTypeSemantics(Type));
17203           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17204                                          Type, ELoc);
17205         } else if (Type->isScalarType()) {
17206           uint64_t Size = Context.getTypeSize(Type);
17207           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
17208           llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
17209           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17210         }
17211         if (Init && OrigType->isAnyComplexType()) {
17212           // Init = 0xFFFF + 0xFFFFi;
17213           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
17214           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
17215         }
17216         Type = OrigType;
17217         break;
17218       }
17219       case BO_LT:
17220       case BO_GT: {
17221         // 'min' reduction op - initializer is 'Largest representable number in
17222         // the reduction list item type'.
17223         // 'max' reduction op - initializer is 'Least representable number in
17224         // the reduction list item type'.
17225         if (Type->isIntegerType() || Type->isPointerType()) {
17226           bool IsSigned = Type->hasSignedIntegerRepresentation();
17227           uint64_t Size = Context.getTypeSize(Type);
17228           QualType IntTy =
17229               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
17230           llvm::APInt InitValue =
17231               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
17232                                         : llvm::APInt::getMinValue(Size)
17233                              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
17234                                         : llvm::APInt::getMaxValue(Size);
17235           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17236           if (Type->isPointerType()) {
17237             // Cast to pointer type.
17238             ExprResult CastExpr = S.BuildCStyleCastExpr(
17239                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
17240             if (CastExpr.isInvalid())
17241               continue;
17242             Init = CastExpr.get();
17243           }
17244         } else if (Type->isRealFloatingType()) {
17245           llvm::APFloat InitValue = llvm::APFloat::getLargest(
17246               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
17247           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17248                                          Type, ELoc);
17249         }
17250         break;
17251       }
17252       case BO_PtrMemD:
17253       case BO_PtrMemI:
17254       case BO_MulAssign:
17255       case BO_Div:
17256       case BO_Rem:
17257       case BO_Sub:
17258       case BO_Shl:
17259       case BO_Shr:
17260       case BO_LE:
17261       case BO_GE:
17262       case BO_EQ:
17263       case BO_NE:
17264       case BO_Cmp:
17265       case BO_AndAssign:
17266       case BO_XorAssign:
17267       case BO_OrAssign:
17268       case BO_Assign:
17269       case BO_AddAssign:
17270       case BO_SubAssign:
17271       case BO_DivAssign:
17272       case BO_RemAssign:
17273       case BO_ShlAssign:
17274       case BO_ShrAssign:
17275       case BO_Comma:
17276         llvm_unreachable("Unexpected reduction operation");
17277       }
17278     }
17279     if (Init && DeclareReductionRef.isUnset()) {
17280       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
17281       // Store initializer for single element in private copy. Will be used
17282       // during codegen.
17283       PrivateVD->setInit(RHSVD->getInit());
17284       PrivateVD->setInitStyle(RHSVD->getInitStyle());
17285     } else if (!Init) {
17286       S.ActOnUninitializedDecl(RHSVD);
17287       // Store initializer for single element in private copy. Will be used
17288       // during codegen.
17289       PrivateVD->setInit(RHSVD->getInit());
17290       PrivateVD->setInitStyle(RHSVD->getInitStyle());
17291     }
17292     if (RHSVD->isInvalidDecl())
17293       continue;
17294     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
17295       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
17296           << Type << ReductionIdRange;
17297       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17298                                VarDecl::DeclarationOnly;
17299       S.Diag(D->getLocation(),
17300              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17301           << D;
17302       continue;
17303     }
17304     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
17305     ExprResult ReductionOp;
17306     if (DeclareReductionRef.isUsable()) {
17307       QualType RedTy = DeclareReductionRef.get()->getType();
17308       QualType PtrRedTy = Context.getPointerType(RedTy);
17309       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
17310       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
17311       if (!BasePath.empty()) {
17312         LHS = S.DefaultLvalueConversion(LHS.get());
17313         RHS = S.DefaultLvalueConversion(RHS.get());
17314         LHS = ImplicitCastExpr::Create(
17315             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
17316             LHS.get()->getValueKind(), FPOptionsOverride());
17317         RHS = ImplicitCastExpr::Create(
17318             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
17319             RHS.get()->getValueKind(), FPOptionsOverride());
17320       }
17321       FunctionProtoType::ExtProtoInfo EPI;
17322       QualType Params[] = {PtrRedTy, PtrRedTy};
17323       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
17324       auto *OVE = new (Context) OpaqueValueExpr(
17325           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
17326           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
17327       Expr *Args[] = {LHS.get(), RHS.get()};
17328       ReductionOp =
17329           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
17330                            S.CurFPFeatureOverrides());
17331     } else {
17332       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
17333       if (Type->isRecordType() && CombBOK != BOK) {
17334         Sema::TentativeAnalysisScope Trap(S);
17335         ReductionOp =
17336             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17337                          CombBOK, LHSDRE, RHSDRE);
17338       }
17339       if (!ReductionOp.isUsable()) {
17340         ReductionOp =
17341             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
17342                          LHSDRE, RHSDRE);
17343         if (ReductionOp.isUsable()) {
17344           if (BOK != BO_LT && BOK != BO_GT) {
17345             ReductionOp =
17346                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17347                              BO_Assign, LHSDRE, ReductionOp.get());
17348           } else {
17349             auto *ConditionalOp = new (Context)
17350                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
17351                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
17352             ReductionOp =
17353                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17354                              BO_Assign, LHSDRE, ConditionalOp);
17355           }
17356         }
17357       }
17358       if (ReductionOp.isUsable())
17359         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
17360                                             /*DiscardedValue*/ false);
17361       if (!ReductionOp.isUsable())
17362         continue;
17363     }
17364 
17365     // Add copy operations for inscan reductions.
17366     // LHS = RHS;
17367     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
17368     if (ClauseKind == OMPC_reduction &&
17369         RD.RedModifier == OMPC_REDUCTION_inscan) {
17370       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
17371       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
17372                                RHS.get());
17373       if (!CopyOpRes.isUsable())
17374         continue;
17375       CopyOpRes =
17376           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
17377       if (!CopyOpRes.isUsable())
17378         continue;
17379       // For simd directive and simd-based directives in simd mode no need to
17380       // construct temp array, need just a single temp element.
17381       if (Stack->getCurrentDirective() == OMPD_simd ||
17382           (S.getLangOpts().OpenMPSimd &&
17383            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
17384         VarDecl *TempArrayVD =
17385             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17386                          D->hasAttrs() ? &D->getAttrs() : nullptr);
17387         // Add a constructor to the temp decl.
17388         S.ActOnUninitializedDecl(TempArrayVD);
17389         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
17390       } else {
17391         // Build temp array for prefix sum.
17392         auto *Dim = new (S.Context)
17393             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17394         QualType ArrayTy =
17395             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
17396                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
17397         VarDecl *TempArrayVD =
17398             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
17399                          D->hasAttrs() ? &D->getAttrs() : nullptr);
17400         // Add a constructor to the temp decl.
17401         S.ActOnUninitializedDecl(TempArrayVD);
17402         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
17403         TempArrayElem =
17404             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
17405         auto *Idx = new (S.Context)
17406             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17407         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
17408                                                           ELoc, Idx, ELoc);
17409       }
17410     }
17411 
17412     // OpenMP [2.15.4.6, Restrictions, p.2]
17413     // A list item that appears in an in_reduction clause of a task construct
17414     // must appear in a task_reduction clause of a construct associated with a
17415     // taskgroup region that includes the participating task in its taskgroup
17416     // set. The construct associated with the innermost region that meets this
17417     // condition must specify the same reduction-identifier as the in_reduction
17418     // clause.
17419     if (ClauseKind == OMPC_in_reduction) {
17420       SourceRange ParentSR;
17421       BinaryOperatorKind ParentBOK;
17422       const Expr *ParentReductionOp = nullptr;
17423       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
17424       DSAStackTy::DSAVarData ParentBOKDSA =
17425           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
17426                                                   ParentBOKTD);
17427       DSAStackTy::DSAVarData ParentReductionOpDSA =
17428           Stack->getTopMostTaskgroupReductionData(
17429               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
17430       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
17431       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
17432       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
17433           (DeclareReductionRef.isUsable() && IsParentBOK) ||
17434           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
17435         bool EmitError = true;
17436         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
17437           llvm::FoldingSetNodeID RedId, ParentRedId;
17438           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
17439           DeclareReductionRef.get()->Profile(RedId, Context,
17440                                              /*Canonical=*/true);
17441           EmitError = RedId != ParentRedId;
17442         }
17443         if (EmitError) {
17444           S.Diag(ReductionId.getBeginLoc(),
17445                  diag::err_omp_reduction_identifier_mismatch)
17446               << ReductionIdRange << RefExpr->getSourceRange();
17447           S.Diag(ParentSR.getBegin(),
17448                  diag::note_omp_previous_reduction_identifier)
17449               << ParentSR
17450               << (IsParentBOK ? ParentBOKDSA.RefExpr
17451                               : ParentReductionOpDSA.RefExpr)
17452                      ->getSourceRange();
17453           continue;
17454         }
17455       }
17456       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
17457     }
17458 
17459     DeclRefExpr *Ref = nullptr;
17460     Expr *VarsExpr = RefExpr->IgnoreParens();
17461     if (!VD && !S.CurContext->isDependentContext()) {
17462       if (ASE || OASE) {
17463         TransformExprToCaptures RebuildToCapture(S, D);
17464         VarsExpr =
17465             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
17466         Ref = RebuildToCapture.getCapturedExpr();
17467       } else {
17468         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
17469       }
17470       if (!S.isOpenMPCapturedDecl(D)) {
17471         RD.ExprCaptures.emplace_back(Ref->getDecl());
17472         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17473           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
17474           if (!RefRes.isUsable())
17475             continue;
17476           ExprResult PostUpdateRes =
17477               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17478                            RefRes.get());
17479           if (!PostUpdateRes.isUsable())
17480             continue;
17481           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
17482               Stack->getCurrentDirective() == OMPD_taskgroup) {
17483             S.Diag(RefExpr->getExprLoc(),
17484                    diag::err_omp_reduction_non_addressable_expression)
17485                 << RefExpr->getSourceRange();
17486             continue;
17487           }
17488           RD.ExprPostUpdates.emplace_back(
17489               S.IgnoredValueConversions(PostUpdateRes.get()).get());
17490         }
17491       }
17492     }
17493     // All reduction items are still marked as reduction (to do not increase
17494     // code base size).
17495     unsigned Modifier = RD.RedModifier;
17496     // Consider task_reductions as reductions with task modifier. Required for
17497     // correct analysis of in_reduction clauses.
17498     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
17499       Modifier = OMPC_REDUCTION_task;
17500     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
17501                   ASE || OASE);
17502     if (Modifier == OMPC_REDUCTION_task &&
17503         (CurrDir == OMPD_taskgroup ||
17504          ((isOpenMPParallelDirective(CurrDir) ||
17505            isOpenMPWorksharingDirective(CurrDir)) &&
17506           !isOpenMPSimdDirective(CurrDir)))) {
17507       if (DeclareReductionRef.isUsable())
17508         Stack->addTaskgroupReductionData(D, ReductionIdRange,
17509                                          DeclareReductionRef.get());
17510       else
17511         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
17512     }
17513     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
17514             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
17515             TempArrayElem.get());
17516   }
17517   return RD.Vars.empty();
17518 }
17519 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17520 OMPClause *Sema::ActOnOpenMPReductionClause(
17521     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
17522     SourceLocation StartLoc, SourceLocation LParenLoc,
17523     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
17524     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17525     ArrayRef<Expr *> UnresolvedReductions) {
17526   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
17527     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
17528         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
17529                                    /*Last=*/OMPC_REDUCTION_unknown)
17530         << getOpenMPClauseName(OMPC_reduction);
17531     return nullptr;
17532   }
17533   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
17534   // A reduction clause with the inscan reduction-modifier may only appear on a
17535   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
17536   // construct, a parallel worksharing-loop construct or a parallel
17537   // worksharing-loop SIMD construct.
17538   if (Modifier == OMPC_REDUCTION_inscan &&
17539       (DSAStack->getCurrentDirective() != OMPD_for &&
17540        DSAStack->getCurrentDirective() != OMPD_for_simd &&
17541        DSAStack->getCurrentDirective() != OMPD_simd &&
17542        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
17543        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
17544     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
17545     return nullptr;
17546   }
17547 
17548   ReductionData RD(VarList.size(), Modifier);
17549   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
17550                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17551                                   ReductionIdScopeSpec, ReductionId,
17552                                   UnresolvedReductions, RD))
17553     return nullptr;
17554 
17555   return OMPReductionClause::Create(
17556       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
17557       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17558       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
17559       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
17560       buildPreInits(Context, RD.ExprCaptures),
17561       buildPostUpdate(*this, RD.ExprPostUpdates));
17562 }
17563 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17564 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
17565     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17566     SourceLocation ColonLoc, SourceLocation EndLoc,
17567     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17568     ArrayRef<Expr *> UnresolvedReductions) {
17569   ReductionData RD(VarList.size());
17570   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
17571                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17572                                   ReductionIdScopeSpec, ReductionId,
17573                                   UnresolvedReductions, RD))
17574     return nullptr;
17575 
17576   return OMPTaskReductionClause::Create(
17577       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17578       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17579       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
17580       buildPreInits(Context, RD.ExprCaptures),
17581       buildPostUpdate(*this, RD.ExprPostUpdates));
17582 }
17583 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17584 OMPClause *Sema::ActOnOpenMPInReductionClause(
17585     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17586     SourceLocation ColonLoc, SourceLocation EndLoc,
17587     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17588     ArrayRef<Expr *> UnresolvedReductions) {
17589   ReductionData RD(VarList.size());
17590   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
17591                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17592                                   ReductionIdScopeSpec, ReductionId,
17593                                   UnresolvedReductions, RD))
17594     return nullptr;
17595 
17596   return OMPInReductionClause::Create(
17597       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17598       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17599       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
17600       buildPreInits(Context, RD.ExprCaptures),
17601       buildPostUpdate(*this, RD.ExprPostUpdates));
17602 }
17603 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)17604 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
17605                                      SourceLocation LinLoc) {
17606   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
17607       LinKind == OMPC_LINEAR_unknown) {
17608     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
17609     return true;
17610   }
17611   return false;
17612 }
17613 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)17614 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17615                                  OpenMPLinearClauseKind LinKind, QualType Type,
17616                                  bool IsDeclareSimd) {
17617   const auto *VD = dyn_cast_or_null<VarDecl>(D);
17618   // A variable must not have an incomplete type or a reference type.
17619   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17620     return true;
17621   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17622       !Type->isReferenceType()) {
17623     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17624         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17625     return true;
17626   }
17627   Type = Type.getNonReferenceType();
17628 
17629   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17630   // A variable that is privatized must not have a const-qualified type
17631   // unless it is of class type with a mutable member. This restriction does
17632   // not apply to the firstprivate clause, nor to the linear clause on
17633   // declarative directives (like declare simd).
17634   if (!IsDeclareSimd &&
17635       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17636     return true;
17637 
17638   // A list item must be of integral or pointer type.
17639   Type = Type.getUnqualifiedType().getCanonicalType();
17640   const auto *Ty = Type.getTypePtrOrNull();
17641   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17642               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17643     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17644     if (D) {
17645       bool IsDecl =
17646           !VD ||
17647           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17648       Diag(D->getLocation(),
17649            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17650           << D;
17651     }
17652     return true;
17653   }
17654   return false;
17655 }
17656 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17657 OMPClause *Sema::ActOnOpenMPLinearClause(
17658     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17659     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17660     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17661   SmallVector<Expr *, 8> Vars;
17662   SmallVector<Expr *, 8> Privates;
17663   SmallVector<Expr *, 8> Inits;
17664   SmallVector<Decl *, 4> ExprCaptures;
17665   SmallVector<Expr *, 4> ExprPostUpdates;
17666   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17667     LinKind = OMPC_LINEAR_val;
17668   for (Expr *RefExpr : VarList) {
17669     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17670     SourceLocation ELoc;
17671     SourceRange ERange;
17672     Expr *SimpleRefExpr = RefExpr;
17673     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17674     if (Res.second) {
17675       // It will be analyzed later.
17676       Vars.push_back(RefExpr);
17677       Privates.push_back(nullptr);
17678       Inits.push_back(nullptr);
17679     }
17680     ValueDecl *D = Res.first;
17681     if (!D)
17682       continue;
17683 
17684     QualType Type = D->getType();
17685     auto *VD = dyn_cast<VarDecl>(D);
17686 
17687     // OpenMP [2.14.3.7, linear clause]
17688     //  A list-item cannot appear in more than one linear clause.
17689     //  A list-item that appears in a linear clause cannot appear in any
17690     //  other data-sharing attribute clause.
17691     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17692     if (DVar.RefExpr) {
17693       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17694                                           << getOpenMPClauseName(OMPC_linear);
17695       reportOriginalDsa(*this, DSAStack, D, DVar);
17696       continue;
17697     }
17698 
17699     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17700       continue;
17701     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17702 
17703     // Build private copy of original var.
17704     VarDecl *Private =
17705         buildVarDecl(*this, ELoc, Type, D->getName(),
17706                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17707                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17708     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17709     // Build var to save initial value.
17710     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17711     Expr *InitExpr;
17712     DeclRefExpr *Ref = nullptr;
17713     if (!VD && !CurContext->isDependentContext()) {
17714       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17715       if (!isOpenMPCapturedDecl(D)) {
17716         ExprCaptures.push_back(Ref->getDecl());
17717         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17718           ExprResult RefRes = DefaultLvalueConversion(Ref);
17719           if (!RefRes.isUsable())
17720             continue;
17721           ExprResult PostUpdateRes =
17722               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
17723                          SimpleRefExpr, RefRes.get());
17724           if (!PostUpdateRes.isUsable())
17725             continue;
17726           ExprPostUpdates.push_back(
17727               IgnoredValueConversions(PostUpdateRes.get()).get());
17728         }
17729       }
17730     }
17731     if (LinKind == OMPC_LINEAR_uval)
17732       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17733     else
17734       InitExpr = VD ? SimpleRefExpr : Ref;
17735     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17736                          /*DirectInit=*/false);
17737     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17738 
17739     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17740     Vars.push_back((VD || CurContext->isDependentContext())
17741                        ? RefExpr->IgnoreParens()
17742                        : Ref);
17743     Privates.push_back(PrivateRef);
17744     Inits.push_back(InitRef);
17745   }
17746 
17747   if (Vars.empty())
17748     return nullptr;
17749 
17750   Expr *StepExpr = Step;
17751   Expr *CalcStepExpr = nullptr;
17752   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17753       !Step->isInstantiationDependent() &&
17754       !Step->containsUnexpandedParameterPack()) {
17755     SourceLocation StepLoc = Step->getBeginLoc();
17756     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17757     if (Val.isInvalid())
17758       return nullptr;
17759     StepExpr = Val.get();
17760 
17761     // Build var to save the step value.
17762     VarDecl *SaveVar =
17763         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17764     ExprResult SaveRef =
17765         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17766     ExprResult CalcStep =
17767         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17768     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17769 
17770     // Warn about zero linear step (it would be probably better specified as
17771     // making corresponding variables 'const').
17772     if (Optional<llvm::APSInt> Result =
17773             StepExpr->getIntegerConstantExpr(Context)) {
17774       if (!Result->isNegative() && !Result->isStrictlyPositive())
17775         Diag(StepLoc, diag::warn_omp_linear_step_zero)
17776             << Vars[0] << (Vars.size() > 1);
17777     } else if (CalcStep.isUsable()) {
17778       // Calculate the step beforehand instead of doing this on each iteration.
17779       // (This is not used if the number of iterations may be kfold-ed).
17780       CalcStepExpr = CalcStep.get();
17781     }
17782   }
17783 
17784   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17785                                  ColonLoc, EndLoc, Vars, Privates, Inits,
17786                                  StepExpr, CalcStepExpr,
17787                                  buildPreInits(Context, ExprCaptures),
17788                                  buildPostUpdate(*this, ExprPostUpdates));
17789 }
17790 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)17791 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17792                                      Expr *NumIterations, Sema &SemaRef,
17793                                      Scope *S, DSAStackTy *Stack) {
17794   // Walk the vars and build update/final expressions for the CodeGen.
17795   SmallVector<Expr *, 8> Updates;
17796   SmallVector<Expr *, 8> Finals;
17797   SmallVector<Expr *, 8> UsedExprs;
17798   Expr *Step = Clause.getStep();
17799   Expr *CalcStep = Clause.getCalcStep();
17800   // OpenMP [2.14.3.7, linear clause]
17801   // If linear-step is not specified it is assumed to be 1.
17802   if (!Step)
17803     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17804   else if (CalcStep)
17805     Step = cast<BinaryOperator>(CalcStep)->getLHS();
17806   bool HasErrors = false;
17807   auto CurInit = Clause.inits().begin();
17808   auto CurPrivate = Clause.privates().begin();
17809   OpenMPLinearClauseKind LinKind = Clause.getModifier();
17810   for (Expr *RefExpr : Clause.varlists()) {
17811     SourceLocation ELoc;
17812     SourceRange ERange;
17813     Expr *SimpleRefExpr = RefExpr;
17814     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17815     ValueDecl *D = Res.first;
17816     if (Res.second || !D) {
17817       Updates.push_back(nullptr);
17818       Finals.push_back(nullptr);
17819       HasErrors = true;
17820       continue;
17821     }
17822     auto &&Info = Stack->isLoopControlVariable(D);
17823     // OpenMP [2.15.11, distribute simd Construct]
17824     // A list item may not appear in a linear clause, unless it is the loop
17825     // iteration variable.
17826     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17827         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17828       SemaRef.Diag(ELoc,
17829                    diag::err_omp_linear_distribute_var_non_loop_iteration);
17830       Updates.push_back(nullptr);
17831       Finals.push_back(nullptr);
17832       HasErrors = true;
17833       continue;
17834     }
17835     Expr *InitExpr = *CurInit;
17836 
17837     // Build privatized reference to the current linear var.
17838     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17839     Expr *CapturedRef;
17840     if (LinKind == OMPC_LINEAR_uval)
17841       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17842     else
17843       CapturedRef =
17844           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17845                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17846                            /*RefersToCapture=*/true);
17847 
17848     // Build update: Var = InitExpr + IV * Step
17849     ExprResult Update;
17850     if (!Info.first)
17851       Update = buildCounterUpdate(
17852           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17853           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17854     else
17855       Update = *CurPrivate;
17856     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17857                                          /*DiscardedValue*/ false);
17858 
17859     // Build final: Var = InitExpr + NumIterations * Step
17860     ExprResult Final;
17861     if (!Info.first)
17862       Final =
17863           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17864                              InitExpr, NumIterations, Step, /*Subtract=*/false,
17865                              /*IsNonRectangularLB=*/false);
17866     else
17867       Final = *CurPrivate;
17868     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17869                                         /*DiscardedValue*/ false);
17870 
17871     if (!Update.isUsable() || !Final.isUsable()) {
17872       Updates.push_back(nullptr);
17873       Finals.push_back(nullptr);
17874       UsedExprs.push_back(nullptr);
17875       HasErrors = true;
17876     } else {
17877       Updates.push_back(Update.get());
17878       Finals.push_back(Final.get());
17879       if (!Info.first)
17880         UsedExprs.push_back(SimpleRefExpr);
17881     }
17882     ++CurInit;
17883     ++CurPrivate;
17884   }
17885   if (Expr *S = Clause.getStep())
17886     UsedExprs.push_back(S);
17887   // Fill the remaining part with the nullptr.
17888   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17889   Clause.setUpdates(Updates);
17890   Clause.setFinals(Finals);
17891   Clause.setUsedExprs(UsedExprs);
17892   return HasErrors;
17893 }
17894 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17895 OMPClause *Sema::ActOnOpenMPAlignedClause(
17896     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17897     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17898   SmallVector<Expr *, 8> Vars;
17899   for (Expr *RefExpr : VarList) {
17900     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17901     SourceLocation ELoc;
17902     SourceRange ERange;
17903     Expr *SimpleRefExpr = RefExpr;
17904     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17905     if (Res.second) {
17906       // It will be analyzed later.
17907       Vars.push_back(RefExpr);
17908     }
17909     ValueDecl *D = Res.first;
17910     if (!D)
17911       continue;
17912 
17913     QualType QType = D->getType();
17914     auto *VD = dyn_cast<VarDecl>(D);
17915 
17916     // OpenMP  [2.8.1, simd construct, Restrictions]
17917     // The type of list items appearing in the aligned clause must be
17918     // array, pointer, reference to array, or reference to pointer.
17919     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17920     const Type *Ty = QType.getTypePtrOrNull();
17921     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17922       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17923           << QType << getLangOpts().CPlusPlus << ERange;
17924       bool IsDecl =
17925           !VD ||
17926           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17927       Diag(D->getLocation(),
17928            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17929           << D;
17930       continue;
17931     }
17932 
17933     // OpenMP  [2.8.1, simd construct, Restrictions]
17934     // A list-item cannot appear in more than one aligned clause.
17935     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
17936       Diag(ELoc, diag::err_omp_used_in_clause_twice)
17937           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17938       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17939           << getOpenMPClauseName(OMPC_aligned);
17940       continue;
17941     }
17942 
17943     DeclRefExpr *Ref = nullptr;
17944     if (!VD && isOpenMPCapturedDecl(D))
17945       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17946     Vars.push_back(DefaultFunctionArrayConversion(
17947                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17948                        .get());
17949   }
17950 
17951   // OpenMP [2.8.1, simd construct, Description]
17952   // The parameter of the aligned clause, alignment, must be a constant
17953   // positive integer expression.
17954   // If no optional parameter is specified, implementation-defined default
17955   // alignments for SIMD instructions on the target platforms are assumed.
17956   if (Alignment != nullptr) {
17957     ExprResult AlignResult =
17958         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17959     if (AlignResult.isInvalid())
17960       return nullptr;
17961     Alignment = AlignResult.get();
17962   }
17963   if (Vars.empty())
17964     return nullptr;
17965 
17966   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17967                                   EndLoc, Vars, Alignment);
17968 }
17969 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17970 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17971                                          SourceLocation StartLoc,
17972                                          SourceLocation LParenLoc,
17973                                          SourceLocation EndLoc) {
17974   SmallVector<Expr *, 8> Vars;
17975   SmallVector<Expr *, 8> SrcExprs;
17976   SmallVector<Expr *, 8> DstExprs;
17977   SmallVector<Expr *, 8> AssignmentOps;
17978   for (Expr *RefExpr : VarList) {
17979     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
17980     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17981       // It will be analyzed later.
17982       Vars.push_back(RefExpr);
17983       SrcExprs.push_back(nullptr);
17984       DstExprs.push_back(nullptr);
17985       AssignmentOps.push_back(nullptr);
17986       continue;
17987     }
17988 
17989     SourceLocation ELoc = RefExpr->getExprLoc();
17990     // OpenMP [2.1, C/C++]
17991     //  A list item is a variable name.
17992     // OpenMP  [2.14.4.1, Restrictions, p.1]
17993     //  A list item that appears in a copyin clause must be threadprivate.
17994     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17995     if (!DE || !isa<VarDecl>(DE->getDecl())) {
17996       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17997           << 0 << RefExpr->getSourceRange();
17998       continue;
17999     }
18000 
18001     Decl *D = DE->getDecl();
18002     auto *VD = cast<VarDecl>(D);
18003 
18004     QualType Type = VD->getType();
18005     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
18006       // It will be analyzed later.
18007       Vars.push_back(DE);
18008       SrcExprs.push_back(nullptr);
18009       DstExprs.push_back(nullptr);
18010       AssignmentOps.push_back(nullptr);
18011       continue;
18012     }
18013 
18014     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
18015     //  A list item that appears in a copyin clause must be threadprivate.
18016     if (!DSAStack->isThreadPrivate(VD)) {
18017       Diag(ELoc, diag::err_omp_required_access)
18018           << getOpenMPClauseName(OMPC_copyin)
18019           << getOpenMPDirectiveName(OMPD_threadprivate);
18020       continue;
18021     }
18022 
18023     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
18024     //  A variable of class type (or array thereof) that appears in a
18025     //  copyin clause requires an accessible, unambiguous copy assignment
18026     //  operator for the class type.
18027     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18028     VarDecl *SrcVD =
18029         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
18030                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
18031     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
18032         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
18033     VarDecl *DstVD =
18034         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
18035                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
18036     DeclRefExpr *PseudoDstExpr =
18037         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
18038     // For arrays generate assignment operation for single element and replace
18039     // it by the original array element in CodeGen.
18040     ExprResult AssignmentOp =
18041         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
18042                    PseudoSrcExpr);
18043     if (AssignmentOp.isInvalid())
18044       continue;
18045     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
18046                                        /*DiscardedValue*/ false);
18047     if (AssignmentOp.isInvalid())
18048       continue;
18049 
18050     DSAStack->addDSA(VD, DE, OMPC_copyin);
18051     Vars.push_back(DE);
18052     SrcExprs.push_back(PseudoSrcExpr);
18053     DstExprs.push_back(PseudoDstExpr);
18054     AssignmentOps.push_back(AssignmentOp.get());
18055   }
18056 
18057   if (Vars.empty())
18058     return nullptr;
18059 
18060   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18061                                  SrcExprs, DstExprs, AssignmentOps);
18062 }
18063 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18064 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
18065                                               SourceLocation StartLoc,
18066                                               SourceLocation LParenLoc,
18067                                               SourceLocation EndLoc) {
18068   SmallVector<Expr *, 8> Vars;
18069   SmallVector<Expr *, 8> SrcExprs;
18070   SmallVector<Expr *, 8> DstExprs;
18071   SmallVector<Expr *, 8> AssignmentOps;
18072   for (Expr *RefExpr : VarList) {
18073     assert(RefExpr && "NULL expr in OpenMP linear clause.");
18074     SourceLocation ELoc;
18075     SourceRange ERange;
18076     Expr *SimpleRefExpr = RefExpr;
18077     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18078     if (Res.second) {
18079       // It will be analyzed later.
18080       Vars.push_back(RefExpr);
18081       SrcExprs.push_back(nullptr);
18082       DstExprs.push_back(nullptr);
18083       AssignmentOps.push_back(nullptr);
18084     }
18085     ValueDecl *D = Res.first;
18086     if (!D)
18087       continue;
18088 
18089     QualType Type = D->getType();
18090     auto *VD = dyn_cast<VarDecl>(D);
18091 
18092     // OpenMP [2.14.4.2, Restrictions, p.2]
18093     //  A list item that appears in a copyprivate clause may not appear in a
18094     //  private or firstprivate clause on the single construct.
18095     if (!VD || !DSAStack->isThreadPrivate(VD)) {
18096       DSAStackTy::DSAVarData DVar =
18097           DSAStack->getTopDSA(D, /*FromParent=*/false);
18098       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
18099           DVar.RefExpr) {
18100         Diag(ELoc, diag::err_omp_wrong_dsa)
18101             << getOpenMPClauseName(DVar.CKind)
18102             << getOpenMPClauseName(OMPC_copyprivate);
18103         reportOriginalDsa(*this, DSAStack, D, DVar);
18104         continue;
18105       }
18106 
18107       // OpenMP [2.11.4.2, Restrictions, p.1]
18108       //  All list items that appear in a copyprivate clause must be either
18109       //  threadprivate or private in the enclosing context.
18110       if (DVar.CKind == OMPC_unknown) {
18111         DVar = DSAStack->getImplicitDSA(D, false);
18112         if (DVar.CKind == OMPC_shared) {
18113           Diag(ELoc, diag::err_omp_required_access)
18114               << getOpenMPClauseName(OMPC_copyprivate)
18115               << "threadprivate or private in the enclosing context";
18116           reportOriginalDsa(*this, DSAStack, D, DVar);
18117           continue;
18118         }
18119       }
18120     }
18121 
18122     // Variably modified types are not supported.
18123     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
18124       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18125           << getOpenMPClauseName(OMPC_copyprivate) << Type
18126           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18127       bool IsDecl =
18128           !VD ||
18129           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
18130       Diag(D->getLocation(),
18131            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18132           << D;
18133       continue;
18134     }
18135 
18136     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
18137     //  A variable of class type (or array thereof) that appears in a
18138     //  copyin clause requires an accessible, unambiguous copy assignment
18139     //  operator for the class type.
18140     Type = Context.getBaseElementType(Type.getNonReferenceType())
18141                .getUnqualifiedType();
18142     VarDecl *SrcVD =
18143         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
18144                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18145     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
18146     VarDecl *DstVD =
18147         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
18148                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18149     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18150     ExprResult AssignmentOp = BuildBinOp(
18151         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
18152     if (AssignmentOp.isInvalid())
18153       continue;
18154     AssignmentOp =
18155         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18156     if (AssignmentOp.isInvalid())
18157       continue;
18158 
18159     // No need to mark vars as copyprivate, they are already threadprivate or
18160     // implicitly private.
18161     assert(VD || isOpenMPCapturedDecl(D));
18162     Vars.push_back(
18163         VD ? RefExpr->IgnoreParens()
18164            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
18165     SrcExprs.push_back(PseudoSrcExpr);
18166     DstExprs.push_back(PseudoDstExpr);
18167     AssignmentOps.push_back(AssignmentOp.get());
18168   }
18169 
18170   if (Vars.empty())
18171     return nullptr;
18172 
18173   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18174                                       Vars, SrcExprs, DstExprs, AssignmentOps);
18175 }
18176 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18177 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
18178                                         SourceLocation StartLoc,
18179                                         SourceLocation LParenLoc,
18180                                         SourceLocation EndLoc) {
18181   if (VarList.empty())
18182     return nullptr;
18183 
18184   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
18185 }
18186 
18187 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)18188 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
18189                            bool Diagnose = true) {
18190   QualType OMPDependT = Stack->getOMPDependT();
18191   if (!OMPDependT.isNull())
18192     return true;
18193   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
18194   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18195   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18196     if (Diagnose)
18197       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
18198     return false;
18199   }
18200   Stack->setOMPDependT(PT.get());
18201   return true;
18202 }
18203 
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18204 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
18205                                          SourceLocation LParenLoc,
18206                                          SourceLocation EndLoc) {
18207   if (!Depobj)
18208     return nullptr;
18209 
18210   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
18211 
18212   // OpenMP 5.0, 2.17.10.1 depobj Construct
18213   // depobj is an lvalue expression of type omp_depend_t.
18214   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
18215       !Depobj->isInstantiationDependent() &&
18216       !Depobj->containsUnexpandedParameterPack() &&
18217       (OMPDependTFound &&
18218        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
18219                                    /*CompareUnqualified=*/true))) {
18220     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18221         << 0 << Depobj->getType() << Depobj->getSourceRange();
18222   }
18223 
18224   if (!Depobj->isLValue()) {
18225     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18226         << 1 << Depobj->getSourceRange();
18227   }
18228 
18229   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
18230 }
18231 
18232 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18233 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
18234                               SourceLocation DepLoc, SourceLocation ColonLoc,
18235                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18236                               SourceLocation LParenLoc, SourceLocation EndLoc) {
18237   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
18238       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
18239     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18240         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
18241     return nullptr;
18242   }
18243   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
18244        DSAStack->getCurrentDirective() == OMPD_depobj) &&
18245       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
18246        DepKind == OMPC_DEPEND_sink ||
18247        ((LangOpts.OpenMP < 50 ||
18248          DSAStack->getCurrentDirective() == OMPD_depobj) &&
18249         DepKind == OMPC_DEPEND_depobj))) {
18250     SmallVector<unsigned, 3> Except;
18251     Except.push_back(OMPC_DEPEND_source);
18252     Except.push_back(OMPC_DEPEND_sink);
18253     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
18254       Except.push_back(OMPC_DEPEND_depobj);
18255     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
18256                                ? "depend modifier(iterator) or "
18257                                : "";
18258     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18259         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
18260                                               /*Last=*/OMPC_DEPEND_unknown,
18261                                               Except)
18262         << getOpenMPClauseName(OMPC_depend);
18263     return nullptr;
18264   }
18265   if (DepModifier &&
18266       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
18267     Diag(DepModifier->getExprLoc(),
18268          diag::err_omp_depend_sink_source_with_modifier);
18269     return nullptr;
18270   }
18271   if (DepModifier &&
18272       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
18273     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
18274 
18275   SmallVector<Expr *, 8> Vars;
18276   DSAStackTy::OperatorOffsetTy OpsOffs;
18277   llvm::APSInt DepCounter(/*BitWidth=*/32);
18278   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
18279   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
18280     if (const Expr *OrderedCountExpr =
18281             DSAStack->getParentOrderedRegionParam().first) {
18282       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
18283       TotalDepCount.setIsUnsigned(/*Val=*/true);
18284     }
18285   }
18286   for (Expr *RefExpr : VarList) {
18287     assert(RefExpr && "NULL expr in OpenMP shared clause.");
18288     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
18289       // It will be analyzed later.
18290       Vars.push_back(RefExpr);
18291       continue;
18292     }
18293 
18294     SourceLocation ELoc = RefExpr->getExprLoc();
18295     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
18296     if (DepKind == OMPC_DEPEND_sink) {
18297       if (DSAStack->getParentOrderedRegionParam().first &&
18298           DepCounter >= TotalDepCount) {
18299         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
18300         continue;
18301       }
18302       ++DepCounter;
18303       // OpenMP  [2.13.9, Summary]
18304       // depend(dependence-type : vec), where dependence-type is:
18305       // 'sink' and where vec is the iteration vector, which has the form:
18306       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
18307       // where n is the value specified by the ordered clause in the loop
18308       // directive, xi denotes the loop iteration variable of the i-th nested
18309       // loop associated with the loop directive, and di is a constant
18310       // non-negative integer.
18311       if (CurContext->isDependentContext()) {
18312         // It will be analyzed later.
18313         Vars.push_back(RefExpr);
18314         continue;
18315       }
18316       SimpleExpr = SimpleExpr->IgnoreImplicit();
18317       OverloadedOperatorKind OOK = OO_None;
18318       SourceLocation OOLoc;
18319       Expr *LHS = SimpleExpr;
18320       Expr *RHS = nullptr;
18321       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
18322         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
18323         OOLoc = BO->getOperatorLoc();
18324         LHS = BO->getLHS()->IgnoreParenImpCasts();
18325         RHS = BO->getRHS()->IgnoreParenImpCasts();
18326       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
18327         OOK = OCE->getOperator();
18328         OOLoc = OCE->getOperatorLoc();
18329         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18330         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
18331       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
18332         OOK = MCE->getMethodDecl()
18333                   ->getNameInfo()
18334                   .getName()
18335                   .getCXXOverloadedOperator();
18336         OOLoc = MCE->getCallee()->getExprLoc();
18337         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
18338         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18339       }
18340       SourceLocation ELoc;
18341       SourceRange ERange;
18342       auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
18343       if (Res.second) {
18344         // It will be analyzed later.
18345         Vars.push_back(RefExpr);
18346       }
18347       ValueDecl *D = Res.first;
18348       if (!D)
18349         continue;
18350 
18351       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
18352         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
18353         continue;
18354       }
18355       if (RHS) {
18356         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
18357             RHS, OMPC_depend, /*StrictlyPositive=*/false);
18358         if (RHSRes.isInvalid())
18359           continue;
18360       }
18361       if (!CurContext->isDependentContext() &&
18362           DSAStack->getParentOrderedRegionParam().first &&
18363           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
18364         const ValueDecl *VD =
18365             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
18366         if (VD)
18367           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
18368               << 1 << VD;
18369         else
18370           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
18371         continue;
18372       }
18373       OpsOffs.emplace_back(RHS, OOK);
18374     } else {
18375       bool OMPDependTFound = LangOpts.OpenMP >= 50;
18376       if (OMPDependTFound)
18377         OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
18378                                          DepKind == OMPC_DEPEND_depobj);
18379       if (DepKind == OMPC_DEPEND_depobj) {
18380         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18381         // List items used in depend clauses with the depobj dependence type
18382         // must be expressions of the omp_depend_t type.
18383         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18384             !RefExpr->isInstantiationDependent() &&
18385             !RefExpr->containsUnexpandedParameterPack() &&
18386             (OMPDependTFound &&
18387              !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
18388                                              RefExpr->getType()))) {
18389           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18390               << 0 << RefExpr->getType() << RefExpr->getSourceRange();
18391           continue;
18392         }
18393         if (!RefExpr->isLValue()) {
18394           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18395               << 1 << RefExpr->getType() << RefExpr->getSourceRange();
18396           continue;
18397         }
18398       } else {
18399         // OpenMP 5.0 [2.17.11, Restrictions]
18400         // List items used in depend clauses cannot be zero-length array
18401         // sections.
18402         QualType ExprTy = RefExpr->getType().getNonReferenceType();
18403         const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
18404         if (OASE) {
18405           QualType BaseType =
18406               OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18407           if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18408             ExprTy = ATy->getElementType();
18409           else
18410             ExprTy = BaseType->getPointeeType();
18411           ExprTy = ExprTy.getNonReferenceType();
18412           const Expr *Length = OASE->getLength();
18413           Expr::EvalResult Result;
18414           if (Length && !Length->isValueDependent() &&
18415               Length->EvaluateAsInt(Result, Context) &&
18416               Result.Val.getInt().isZero()) {
18417             Diag(ELoc,
18418                  diag::err_omp_depend_zero_length_array_section_not_allowed)
18419                 << SimpleExpr->getSourceRange();
18420             continue;
18421           }
18422         }
18423 
18424         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18425         // List items used in depend clauses with the in, out, inout or
18426         // mutexinoutset dependence types cannot be expressions of the
18427         // omp_depend_t type.
18428         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18429             !RefExpr->isInstantiationDependent() &&
18430             !RefExpr->containsUnexpandedParameterPack() &&
18431             (OMPDependTFound &&
18432              DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
18433           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18434               << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
18435               << RefExpr->getSourceRange();
18436           continue;
18437         }
18438 
18439         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
18440         if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
18441             (ASE && !ASE->getBase()->isTypeDependent() &&
18442              !ASE->getBase()
18443                   ->getType()
18444                   .getNonReferenceType()
18445                   ->isPointerType() &&
18446              !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
18447           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18448               << (LangOpts.OpenMP >= 50 ? 1 : 0)
18449               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18450           continue;
18451         }
18452 
18453         ExprResult Res;
18454         {
18455           Sema::TentativeAnalysisScope Trap(*this);
18456           Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
18457                                      RefExpr->IgnoreParenImpCasts());
18458         }
18459         if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
18460             !isa<OMPArrayShapingExpr>(SimpleExpr)) {
18461           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18462               << (LangOpts.OpenMP >= 50 ? 1 : 0)
18463               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18464           continue;
18465         }
18466       }
18467     }
18468     Vars.push_back(RefExpr->IgnoreParenImpCasts());
18469   }
18470 
18471   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
18472       TotalDepCount > VarList.size() &&
18473       DSAStack->getParentOrderedRegionParam().first &&
18474       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
18475     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
18476         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
18477   }
18478   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
18479       Vars.empty())
18480     return nullptr;
18481 
18482   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18483                                     DepModifier, DepKind, DepLoc, ColonLoc,
18484                                     Vars, TotalDepCount.getZExtValue());
18485   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
18486       DSAStack->isParentOrderedRegion())
18487     DSAStack->addDoacrossDependClause(C, OpsOffs);
18488   return C;
18489 }
18490 
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)18491 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
18492                                          Expr *Device, SourceLocation StartLoc,
18493                                          SourceLocation LParenLoc,
18494                                          SourceLocation ModifierLoc,
18495                                          SourceLocation EndLoc) {
18496   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
18497          "Unexpected device modifier in OpenMP < 50.");
18498 
18499   bool ErrorFound = false;
18500   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
18501     std::string Values =
18502         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
18503     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
18504         << Values << getOpenMPClauseName(OMPC_device);
18505     ErrorFound = true;
18506   }
18507 
18508   Expr *ValExpr = Device;
18509   Stmt *HelperValStmt = nullptr;
18510 
18511   // OpenMP [2.9.1, Restrictions]
18512   // The device expression must evaluate to a non-negative integer value.
18513   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
18514                                           /*StrictlyPositive=*/false) ||
18515                ErrorFound;
18516   if (ErrorFound)
18517     return nullptr;
18518 
18519   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18520   OpenMPDirectiveKind CaptureRegion =
18521       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
18522   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18523     ValExpr = MakeFullExpr(ValExpr).get();
18524     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18525     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18526     HelperValStmt = buildPreInits(Context, Captures);
18527   }
18528 
18529   return new (Context)
18530       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
18531                       LParenLoc, ModifierLoc, EndLoc);
18532 }
18533 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)18534 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
18535                               DSAStackTy *Stack, QualType QTy,
18536                               bool FullCheck = true) {
18537   if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
18538     return false;
18539   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
18540       !QTy.isTriviallyCopyableType(SemaRef.Context))
18541     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
18542   return true;
18543 }
18544 
18545 /// Return true if it can be proven that the provided array expression
18546 /// (array section or array subscript) does NOT specify the whole size of the
18547 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18548 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
18549                                                         const Expr *E,
18550                                                         QualType BaseQTy) {
18551   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18552 
18553   // If this is an array subscript, it refers to the whole size if the size of
18554   // the dimension is constant and equals 1. Also, an array section assumes the
18555   // format of an array subscript if no colon is used.
18556   if (isa<ArraySubscriptExpr>(E) ||
18557       (OASE && OASE->getColonLocFirst().isInvalid())) {
18558     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18559       return ATy->getSize().getSExtValue() != 1;
18560     // Size can't be evaluated statically.
18561     return false;
18562   }
18563 
18564   assert(OASE && "Expecting array section if not an array subscript.");
18565   const Expr *LowerBound = OASE->getLowerBound();
18566   const Expr *Length = OASE->getLength();
18567 
18568   // If there is a lower bound that does not evaluates to zero, we are not
18569   // covering the whole dimension.
18570   if (LowerBound) {
18571     Expr::EvalResult Result;
18572     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
18573       return false; // Can't get the integer value as a constant.
18574 
18575     llvm::APSInt ConstLowerBound = Result.Val.getInt();
18576     if (ConstLowerBound.getSExtValue())
18577       return true;
18578   }
18579 
18580   // If we don't have a length we covering the whole dimension.
18581   if (!Length)
18582     return false;
18583 
18584   // If the base is a pointer, we don't have a way to get the size of the
18585   // pointee.
18586   if (BaseQTy->isPointerType())
18587     return false;
18588 
18589   // We can only check if the length is the same as the size of the dimension
18590   // if we have a constant array.
18591   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
18592   if (!CATy)
18593     return false;
18594 
18595   Expr::EvalResult Result;
18596   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18597     return false; // Can't get the integer value as a constant.
18598 
18599   llvm::APSInt ConstLength = Result.Val.getInt();
18600   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
18601 }
18602 
18603 // Return true if it can be proven that the provided array expression (array
18604 // section or array subscript) does NOT specify a single element of the array
18605 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18606 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
18607                                                         const Expr *E,
18608                                                         QualType BaseQTy) {
18609   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18610 
18611   // An array subscript always refer to a single element. Also, an array section
18612   // assumes the format of an array subscript if no colon is used.
18613   if (isa<ArraySubscriptExpr>(E) ||
18614       (OASE && OASE->getColonLocFirst().isInvalid()))
18615     return false;
18616 
18617   assert(OASE && "Expecting array section if not an array subscript.");
18618   const Expr *Length = OASE->getLength();
18619 
18620   // If we don't have a length we have to check if the array has unitary size
18621   // for this dimension. Also, we should always expect a length if the base type
18622   // is pointer.
18623   if (!Length) {
18624     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18625       return ATy->getSize().getSExtValue() != 1;
18626     // We cannot assume anything.
18627     return false;
18628   }
18629 
18630   // Check if the length evaluates to 1.
18631   Expr::EvalResult Result;
18632   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18633     return false; // Can't get the integer value as a constant.
18634 
18635   llvm::APSInt ConstLength = Result.Val.getInt();
18636   return ConstLength.getSExtValue() != 1;
18637 }
18638 
18639 // The base of elements of list in a map clause have to be either:
18640 //  - a reference to variable or field.
18641 //  - a member expression.
18642 //  - an array expression.
18643 //
18644 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18645 // reference to 'r'.
18646 //
18647 // If we have:
18648 //
18649 // struct SS {
18650 //   Bla S;
18651 //   foo() {
18652 //     #pragma omp target map (S.Arr[:12]);
18653 //   }
18654 // }
18655 //
18656 // We want to retrieve the member expression 'this->S';
18657 
18658 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18659 //  If a list item is an array section, it must specify contiguous storage.
18660 //
18661 // For this restriction it is sufficient that we make sure only references
18662 // to variables or fields and array expressions, and that no array sections
18663 // exist except in the rightmost expression (unless they cover the whole
18664 // dimension of the array). E.g. these would be invalid:
18665 //
18666 //   r.ArrS[3:5].Arr[6:7]
18667 //
18668 //   r.ArrS[3:5].x
18669 //
18670 // but these would be valid:
18671 //   r.ArrS[3].Arr[6:7]
18672 //
18673 //   r.ArrS[3].x
18674 namespace {
18675 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18676   Sema &SemaRef;
18677   OpenMPClauseKind CKind = OMPC_unknown;
18678   OpenMPDirectiveKind DKind = OMPD_unknown;
18679   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18680   bool IsNonContiguous = false;
18681   bool NoDiagnose = false;
18682   const Expr *RelevantExpr = nullptr;
18683   bool AllowUnitySizeArraySection = true;
18684   bool AllowWholeSizeArraySection = true;
18685   bool AllowAnotherPtr = true;
18686   SourceLocation ELoc;
18687   SourceRange ERange;
18688 
emitErrorMsg()18689   void emitErrorMsg() {
18690     // If nothing else worked, this is not a valid map clause expression.
18691     if (SemaRef.getLangOpts().OpenMP < 50) {
18692       SemaRef.Diag(ELoc,
18693                    diag::err_omp_expected_named_var_member_or_array_expression)
18694           << ERange;
18695     } else {
18696       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18697           << getOpenMPClauseName(CKind) << ERange;
18698     }
18699   }
18700 
18701 public:
VisitDeclRefExpr(DeclRefExpr * DRE)18702   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18703     if (!isa<VarDecl>(DRE->getDecl())) {
18704       emitErrorMsg();
18705       return false;
18706     }
18707     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18708     RelevantExpr = DRE;
18709     // Record the component.
18710     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18711     return true;
18712   }
18713 
VisitMemberExpr(MemberExpr * ME)18714   bool VisitMemberExpr(MemberExpr *ME) {
18715     Expr *E = ME;
18716     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18717 
18718     if (isa<CXXThisExpr>(BaseE)) {
18719       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18720       // We found a base expression: this->Val.
18721       RelevantExpr = ME;
18722     } else {
18723       E = BaseE;
18724     }
18725 
18726     if (!isa<FieldDecl>(ME->getMemberDecl())) {
18727       if (!NoDiagnose) {
18728         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18729           << ME->getSourceRange();
18730         return false;
18731       }
18732       if (RelevantExpr)
18733         return false;
18734       return Visit(E);
18735     }
18736 
18737     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18738 
18739     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18740     //  A bit-field cannot appear in a map clause.
18741     //
18742     if (FD->isBitField()) {
18743       if (!NoDiagnose) {
18744         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18745           << ME->getSourceRange() << getOpenMPClauseName(CKind);
18746         return false;
18747       }
18748       if (RelevantExpr)
18749         return false;
18750       return Visit(E);
18751     }
18752 
18753     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18754     //  If the type of a list item is a reference to a type T then the type
18755     //  will be considered to be T for all purposes of this clause.
18756     QualType CurType = BaseE->getType().getNonReferenceType();
18757 
18758     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18759     //  A list item cannot be a variable that is a member of a structure with
18760     //  a union type.
18761     //
18762     if (CurType->isUnionType()) {
18763       if (!NoDiagnose) {
18764         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18765           << ME->getSourceRange();
18766         return false;
18767       }
18768       return RelevantExpr || Visit(E);
18769     }
18770 
18771     // If we got a member expression, we should not expect any array section
18772     // before that:
18773     //
18774     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18775     //  If a list item is an element of a structure, only the rightmost symbol
18776     //  of the variable reference can be an array section.
18777     //
18778     AllowUnitySizeArraySection = false;
18779     AllowWholeSizeArraySection = false;
18780 
18781     // Record the component.
18782     Components.emplace_back(ME, FD, IsNonContiguous);
18783     return RelevantExpr || Visit(E);
18784   }
18785 
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)18786   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18787     Expr *E = AE->getBase()->IgnoreParenImpCasts();
18788 
18789     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
18790       if (!NoDiagnose) {
18791         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18792           << 0 << AE->getSourceRange();
18793         return false;
18794       }
18795       return RelevantExpr || Visit(E);
18796     }
18797 
18798     // If we got an array subscript that express the whole dimension we
18799     // can have any array expressions before. If it only expressing part of
18800     // the dimension, we can only have unitary-size array expressions.
18801     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
18802                                                     E->getType()))
18803       AllowWholeSizeArraySection = false;
18804 
18805     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18806       Expr::EvalResult Result;
18807       if (!AE->getIdx()->isValueDependent() &&
18808           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18809           !Result.Val.getInt().isZero()) {
18810         SemaRef.Diag(AE->getIdx()->getExprLoc(),
18811                      diag::err_omp_invalid_map_this_expr);
18812         SemaRef.Diag(AE->getIdx()->getExprLoc(),
18813                      diag::note_omp_invalid_subscript_on_this_ptr_map);
18814       }
18815       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18816       RelevantExpr = TE;
18817     }
18818 
18819     // Record the component - we don't have any declaration associated.
18820     Components.emplace_back(AE, nullptr, IsNonContiguous);
18821 
18822     return RelevantExpr || Visit(E);
18823   }
18824 
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)18825   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18826     // After OMP 5.0  Array section in reduction clause will be implicitly
18827     // mapped
18828     assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
18829            "Array sections cannot be implicitly mapped.");
18830     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18831     QualType CurType =
18832       OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18833 
18834     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18835     //  If the type of a list item is a reference to a type T then the type
18836     //  will be considered to be T for all purposes of this clause.
18837     if (CurType->isReferenceType())
18838       CurType = CurType->getPointeeType();
18839 
18840     bool IsPointer = CurType->isAnyPointerType();
18841 
18842     if (!IsPointer && !CurType->isArrayType()) {
18843       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18844         << 0 << OASE->getSourceRange();
18845       return false;
18846     }
18847 
18848     bool NotWhole =
18849       checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18850     bool NotUnity =
18851       checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18852 
18853     if (AllowWholeSizeArraySection) {
18854       // Any array section is currently allowed. Allowing a whole size array
18855       // section implies allowing a unity array section as well.
18856       //
18857       // If this array section refers to the whole dimension we can still
18858       // accept other array sections before this one, except if the base is a
18859       // pointer. Otherwise, only unitary sections are accepted.
18860       if (NotWhole || IsPointer)
18861         AllowWholeSizeArraySection = false;
18862     } else if (DKind == OMPD_target_update &&
18863                SemaRef.getLangOpts().OpenMP >= 50) {
18864       if (IsPointer && !AllowAnotherPtr)
18865         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18866             << /*array of unknown bound */ 1;
18867       else
18868         IsNonContiguous = true;
18869     } else if (AllowUnitySizeArraySection && NotUnity) {
18870       // A unity or whole array section is not allowed and that is not
18871       // compatible with the properties of the current array section.
18872       if (NoDiagnose)
18873         return false;
18874       SemaRef.Diag(
18875         ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18876         << OASE->getSourceRange();
18877       return false;
18878     }
18879 
18880     if (IsPointer)
18881       AllowAnotherPtr = false;
18882 
18883     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18884       Expr::EvalResult ResultR;
18885       Expr::EvalResult ResultL;
18886       if (!OASE->getLength()->isValueDependent() &&
18887           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18888           !ResultR.Val.getInt().isOne()) {
18889         SemaRef.Diag(OASE->getLength()->getExprLoc(),
18890                      diag::err_omp_invalid_map_this_expr);
18891         SemaRef.Diag(OASE->getLength()->getExprLoc(),
18892                      diag::note_omp_invalid_length_on_this_ptr_mapping);
18893       }
18894       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18895           OASE->getLowerBound()->EvaluateAsInt(ResultL,
18896                                                SemaRef.getASTContext()) &&
18897           !ResultL.Val.getInt().isZero()) {
18898         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18899                      diag::err_omp_invalid_map_this_expr);
18900         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18901                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18902       }
18903       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18904       RelevantExpr = TE;
18905     }
18906 
18907     // Record the component - we don't have any declaration associated.
18908     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18909     return RelevantExpr || Visit(E);
18910   }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)18911   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18912     Expr *Base = E->getBase();
18913 
18914     // Record the component - we don't have any declaration associated.
18915     Components.emplace_back(E, nullptr, IsNonContiguous);
18916 
18917     return Visit(Base->IgnoreParenImpCasts());
18918   }
18919 
VisitUnaryOperator(UnaryOperator * UO)18920   bool VisitUnaryOperator(UnaryOperator *UO) {
18921     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18922         UO->getOpcode() != UO_Deref) {
18923       emitErrorMsg();
18924       return false;
18925     }
18926     if (!RelevantExpr) {
18927       // Record the component if haven't found base decl.
18928       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18929     }
18930     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18931   }
VisitBinaryOperator(BinaryOperator * BO)18932   bool VisitBinaryOperator(BinaryOperator *BO) {
18933     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18934       emitErrorMsg();
18935       return false;
18936     }
18937 
18938     // Pointer arithmetic is the only thing we expect to happen here so after we
18939     // make sure the binary operator is a pointer type, the we only thing need
18940     // to to is to visit the subtree that has the same type as root (so that we
18941     // know the other subtree is just an offset)
18942     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18943     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18944     Components.emplace_back(BO, nullptr, false);
18945     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
18946             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
18947            "Either LHS or RHS have base decl inside");
18948     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18949       return RelevantExpr || Visit(LE);
18950     return RelevantExpr || Visit(RE);
18951   }
VisitCXXThisExpr(CXXThisExpr * CTE)18952   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18953     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18954     RelevantExpr = CTE;
18955     Components.emplace_back(CTE, nullptr, IsNonContiguous);
18956     return true;
18957   }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)18958   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18959     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18960     Components.emplace_back(COCE, nullptr, IsNonContiguous);
18961     return true;
18962   }
VisitOpaqueValueExpr(OpaqueValueExpr * E)18963   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18964     Expr *Source = E->getSourceExpr();
18965     if (!Source) {
18966       emitErrorMsg();
18967       return false;
18968     }
18969     return Visit(Source);
18970   }
VisitStmt(Stmt *)18971   bool VisitStmt(Stmt *) {
18972     emitErrorMsg();
18973     return false;
18974   }
getFoundBase() const18975   const Expr *getFoundBase() const {
18976     return RelevantExpr;
18977   }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)18978   explicit MapBaseChecker(
18979       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18980       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18981       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18982       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18983         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18984 };
18985 } // namespace
18986 
18987 /// Return the expression of the base of the mappable expression or null if it
18988 /// cannot be determined and do all the necessary checks to see if the expression
18989 /// is valid as a standalone mappable expression. In the process, record all the
18990 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)18991 static const Expr *checkMapClauseExpressionBase(
18992     Sema &SemaRef, Expr *E,
18993     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18994     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18995   SourceLocation ELoc = E->getExprLoc();
18996   SourceRange ERange = E->getSourceRange();
18997   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18998                          ERange);
18999   if (Checker.Visit(E->IgnoreParens())) {
19000     // Check if the highest dimension array section has length specified
19001     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
19002         (CKind == OMPC_to || CKind == OMPC_from)) {
19003       auto CI = CurComponents.rbegin();
19004       auto CE = CurComponents.rend();
19005       for (; CI != CE; ++CI) {
19006         const auto *OASE =
19007             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
19008         if (!OASE)
19009           continue;
19010         if (OASE && OASE->getLength())
19011           break;
19012         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
19013             << ERange;
19014       }
19015     }
19016     return Checker.getFoundBase();
19017   }
19018   return nullptr;
19019 }
19020 
19021 // Return true if expression E associated with value VD has conflicts with other
19022 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)19023 static bool checkMapConflicts(
19024     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
19025     bool CurrentRegionOnly,
19026     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
19027     OpenMPClauseKind CKind) {
19028   assert(VD && E);
19029   SourceLocation ELoc = E->getExprLoc();
19030   SourceRange ERange = E->getSourceRange();
19031 
19032   // In order to easily check the conflicts we need to match each component of
19033   // the expression under test with the components of the expressions that are
19034   // already in the stack.
19035 
19036   assert(!CurComponents.empty() && "Map clause expression with no components!");
19037   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
19038          "Map clause expression with unexpected base!");
19039 
19040   // Variables to help detecting enclosing problems in data environment nests.
19041   bool IsEnclosedByDataEnvironmentExpr = false;
19042   const Expr *EnclosingExpr = nullptr;
19043 
19044   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
19045       VD, CurrentRegionOnly,
19046       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
19047        ERange, CKind, &EnclosingExpr,
19048        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
19049                           StackComponents,
19050                       OpenMPClauseKind Kind) {
19051         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
19052           return false;
19053         assert(!StackComponents.empty() &&
19054                "Map clause expression with no components!");
19055         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
19056                "Map clause expression with unexpected base!");
19057         (void)VD;
19058 
19059         // The whole expression in the stack.
19060         const Expr *RE = StackComponents.front().getAssociatedExpression();
19061 
19062         // Expressions must start from the same base. Here we detect at which
19063         // point both expressions diverge from each other and see if we can
19064         // detect if the memory referred to both expressions is contiguous and
19065         // do not overlap.
19066         auto CI = CurComponents.rbegin();
19067         auto CE = CurComponents.rend();
19068         auto SI = StackComponents.rbegin();
19069         auto SE = StackComponents.rend();
19070         for (; CI != CE && SI != SE; ++CI, ++SI) {
19071 
19072           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
19073           //  At most one list item can be an array item derived from a given
19074           //  variable in map clauses of the same construct.
19075           if (CurrentRegionOnly &&
19076               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
19077                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
19078                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
19079               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
19080                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
19081                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
19082             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
19083                          diag::err_omp_multiple_array_items_in_map_clause)
19084                 << CI->getAssociatedExpression()->getSourceRange();
19085             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
19086                          diag::note_used_here)
19087                 << SI->getAssociatedExpression()->getSourceRange();
19088             return true;
19089           }
19090 
19091           // Do both expressions have the same kind?
19092           if (CI->getAssociatedExpression()->getStmtClass() !=
19093               SI->getAssociatedExpression()->getStmtClass())
19094             break;
19095 
19096           // Are we dealing with different variables/fields?
19097           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
19098             break;
19099         }
19100         // Check if the extra components of the expressions in the enclosing
19101         // data environment are redundant for the current base declaration.
19102         // If they are, the maps completely overlap, which is legal.
19103         for (; SI != SE; ++SI) {
19104           QualType Type;
19105           if (const auto *ASE =
19106                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
19107             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
19108           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
19109                          SI->getAssociatedExpression())) {
19110             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
19111             Type =
19112                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
19113           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
19114                          SI->getAssociatedExpression())) {
19115             Type = OASE->getBase()->getType()->getPointeeType();
19116           }
19117           if (Type.isNull() || Type->isAnyPointerType() ||
19118               checkArrayExpressionDoesNotReferToWholeSize(
19119                   SemaRef, SI->getAssociatedExpression(), Type))
19120             break;
19121         }
19122 
19123         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19124         //  List items of map clauses in the same construct must not share
19125         //  original storage.
19126         //
19127         // If the expressions are exactly the same or one is a subset of the
19128         // other, it means they are sharing storage.
19129         if (CI == CE && SI == SE) {
19130           if (CurrentRegionOnly) {
19131             if (CKind == OMPC_map) {
19132               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19133             } else {
19134               assert(CKind == OMPC_to || CKind == OMPC_from);
19135               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19136                   << ERange;
19137             }
19138             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19139                 << RE->getSourceRange();
19140             return true;
19141           }
19142           // If we find the same expression in the enclosing data environment,
19143           // that is legal.
19144           IsEnclosedByDataEnvironmentExpr = true;
19145           return false;
19146         }
19147 
19148         QualType DerivedType =
19149             std::prev(CI)->getAssociatedDeclaration()->getType();
19150         SourceLocation DerivedLoc =
19151             std::prev(CI)->getAssociatedExpression()->getExprLoc();
19152 
19153         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19154         //  If the type of a list item is a reference to a type T then the type
19155         //  will be considered to be T for all purposes of this clause.
19156         DerivedType = DerivedType.getNonReferenceType();
19157 
19158         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
19159         //  A variable for which the type is pointer and an array section
19160         //  derived from that variable must not appear as list items of map
19161         //  clauses of the same construct.
19162         //
19163         // Also, cover one of the cases in:
19164         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19165         //  If any part of the original storage of a list item has corresponding
19166         //  storage in the device data environment, all of the original storage
19167         //  must have corresponding storage in the device data environment.
19168         //
19169         if (DerivedType->isAnyPointerType()) {
19170           if (CI == CE || SI == SE) {
19171             SemaRef.Diag(
19172                 DerivedLoc,
19173                 diag::err_omp_pointer_mapped_along_with_derived_section)
19174                 << DerivedLoc;
19175             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19176                 << RE->getSourceRange();
19177             return true;
19178           }
19179           if (CI->getAssociatedExpression()->getStmtClass() !=
19180                          SI->getAssociatedExpression()->getStmtClass() ||
19181                      CI->getAssociatedDeclaration()->getCanonicalDecl() ==
19182                          SI->getAssociatedDeclaration()->getCanonicalDecl()) {
19183             assert(CI != CE && SI != SE);
19184             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
19185                 << DerivedLoc;
19186             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19187                 << RE->getSourceRange();
19188             return true;
19189           }
19190         }
19191 
19192         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19193         //  List items of map clauses in the same construct must not share
19194         //  original storage.
19195         //
19196         // An expression is a subset of the other.
19197         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
19198           if (CKind == OMPC_map) {
19199             if (CI != CE || SI != SE) {
19200               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
19201               // a pointer.
19202               auto Begin =
19203                   CI != CE ? CurComponents.begin() : StackComponents.begin();
19204               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
19205               auto It = Begin;
19206               while (It != End && !It->getAssociatedDeclaration())
19207                 std::advance(It, 1);
19208               assert(It != End &&
19209                      "Expected at least one component with the declaration.");
19210               if (It != Begin && It->getAssociatedDeclaration()
19211                                      ->getType()
19212                                      .getCanonicalType()
19213                                      ->isAnyPointerType()) {
19214                 IsEnclosedByDataEnvironmentExpr = false;
19215                 EnclosingExpr = nullptr;
19216                 return false;
19217               }
19218             }
19219             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19220           } else {
19221             assert(CKind == OMPC_to || CKind == OMPC_from);
19222             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19223                 << ERange;
19224           }
19225           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19226               << RE->getSourceRange();
19227           return true;
19228         }
19229 
19230         // The current expression uses the same base as other expression in the
19231         // data environment but does not contain it completely.
19232         if (!CurrentRegionOnly && SI != SE)
19233           EnclosingExpr = RE;
19234 
19235         // The current expression is a subset of the expression in the data
19236         // environment.
19237         IsEnclosedByDataEnvironmentExpr |=
19238             (!CurrentRegionOnly && CI != CE && SI == SE);
19239 
19240         return false;
19241       });
19242 
19243   if (CurrentRegionOnly)
19244     return FoundError;
19245 
19246   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19247   //  If any part of the original storage of a list item has corresponding
19248   //  storage in the device data environment, all of the original storage must
19249   //  have corresponding storage in the device data environment.
19250   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
19251   //  If a list item is an element of a structure, and a different element of
19252   //  the structure has a corresponding list item in the device data environment
19253   //  prior to a task encountering the construct associated with the map clause,
19254   //  then the list item must also have a corresponding list item in the device
19255   //  data environment prior to the task encountering the construct.
19256   //
19257   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
19258     SemaRef.Diag(ELoc,
19259                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
19260         << ERange;
19261     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
19262         << EnclosingExpr->getSourceRange();
19263     return true;
19264   }
19265 
19266   return FoundError;
19267 }
19268 
19269 // Look up the user-defined mapper given the mapper name and mapped type, and
19270 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)19271 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
19272                                             CXXScopeSpec &MapperIdScopeSpec,
19273                                             const DeclarationNameInfo &MapperId,
19274                                             QualType Type,
19275                                             Expr *UnresolvedMapper) {
19276   if (MapperIdScopeSpec.isInvalid())
19277     return ExprError();
19278   // Get the actual type for the array type.
19279   if (Type->isArrayType()) {
19280     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
19281     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
19282   }
19283   // Find all user-defined mappers with the given MapperId.
19284   SmallVector<UnresolvedSet<8>, 4> Lookups;
19285   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
19286   Lookup.suppressDiagnostics();
19287   if (S) {
19288     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
19289       NamedDecl *D = Lookup.getRepresentativeDecl();
19290       while (S && !S->isDeclScope(D))
19291         S = S->getParent();
19292       if (S)
19293         S = S->getParent();
19294       Lookups.emplace_back();
19295       Lookups.back().append(Lookup.begin(), Lookup.end());
19296       Lookup.clear();
19297     }
19298   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
19299     // Extract the user-defined mappers with the given MapperId.
19300     Lookups.push_back(UnresolvedSet<8>());
19301     for (NamedDecl *D : ULE->decls()) {
19302       auto *DMD = cast<OMPDeclareMapperDecl>(D);
19303       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
19304       Lookups.back().addDecl(DMD);
19305     }
19306   }
19307   // Defer the lookup for dependent types. The results will be passed through
19308   // UnresolvedMapper on instantiation.
19309   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
19310       Type->isInstantiationDependentType() ||
19311       Type->containsUnexpandedParameterPack() ||
19312       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19313         return !D->isInvalidDecl() &&
19314                (D->getType()->isDependentType() ||
19315                 D->getType()->isInstantiationDependentType() ||
19316                 D->getType()->containsUnexpandedParameterPack());
19317       })) {
19318     UnresolvedSet<8> URS;
19319     for (const UnresolvedSet<8> &Set : Lookups) {
19320       if (Set.empty())
19321         continue;
19322       URS.append(Set.begin(), Set.end());
19323     }
19324     return UnresolvedLookupExpr::Create(
19325         SemaRef.Context, /*NamingClass=*/nullptr,
19326         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
19327         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
19328   }
19329   SourceLocation Loc = MapperId.getLoc();
19330   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19331   //  The type must be of struct, union or class type in C and C++
19332   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
19333       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
19334     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
19335     return ExprError();
19336   }
19337   // Perform argument dependent lookup.
19338   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
19339     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
19340   // Return the first user-defined mapper with the desired type.
19341   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19342           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
19343             if (!D->isInvalidDecl() &&
19344                 SemaRef.Context.hasSameType(D->getType(), Type))
19345               return D;
19346             return nullptr;
19347           }))
19348     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19349   // Find the first user-defined mapper with a type derived from the desired
19350   // type.
19351   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19352           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
19353             if (!D->isInvalidDecl() &&
19354                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
19355                 !Type.isMoreQualifiedThan(D->getType()))
19356               return D;
19357             return nullptr;
19358           })) {
19359     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19360                        /*DetectVirtual=*/false);
19361     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
19362       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19363               VD->getType().getUnqualifiedType()))) {
19364         if (SemaRef.CheckBaseClassAccess(
19365                 Loc, VD->getType(), Type, Paths.front(),
19366                 /*DiagID=*/0) != Sema::AR_inaccessible) {
19367           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19368         }
19369       }
19370     }
19371   }
19372   // Report error if a mapper is specified, but cannot be found.
19373   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
19374     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
19375         << Type << MapperId.getName();
19376     return ExprError();
19377   }
19378   return ExprEmpty();
19379 }
19380 
19381 namespace {
19382 // Utility struct that gathers all the related lists associated with a mappable
19383 // expression.
19384 struct MappableVarListInfo {
19385   // The list of expressions.
19386   ArrayRef<Expr *> VarList;
19387   // The list of processed expressions.
19388   SmallVector<Expr *, 16> ProcessedVarList;
19389   // The mappble components for each expression.
19390   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
19391   // The base declaration of the variable.
19392   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
19393   // The reference to the user-defined mapper associated with every expression.
19394   SmallVector<Expr *, 16> UDMapperList;
19395 
MappableVarListInfo__anon850ef1bd5911::MappableVarListInfo19396   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
19397     // We have a list of components and base declarations for each entry in the
19398     // variable list.
19399     VarComponents.reserve(VarList.size());
19400     VarBaseDeclarations.reserve(VarList.size());
19401   }
19402 };
19403 }
19404 
19405 // Check the validity of the provided variable list for the provided clause kind
19406 // \a CKind. In the check process the valid expressions, mappable expression
19407 // components, variables, and user-defined mappers are extracted and used to
19408 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
19409 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
19410 // 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,ArrayRef<OpenMPMapModifierKind> Modifiers=None,bool IsMapTypeImplicit=false,bool NoDiagnose=false)19411 static void checkMappableExpressionList(
19412     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
19413     MappableVarListInfo &MVLI, SourceLocation StartLoc,
19414     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
19415     ArrayRef<Expr *> UnresolvedMappers,
19416     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
19417     ArrayRef<OpenMPMapModifierKind> Modifiers = None,
19418     bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
19419   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
19420   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
19421          "Unexpected clause kind with mappable expressions!");
19422 
19423   // If the identifier of user-defined mapper is not specified, it is "default".
19424   // We do not change the actual name in this clause to distinguish whether a
19425   // mapper is specified explicitly, i.e., it is not explicitly specified when
19426   // MapperId.getName() is empty.
19427   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
19428     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
19429     MapperId.setName(DeclNames.getIdentifier(
19430         &SemaRef.getASTContext().Idents.get("default")));
19431     MapperId.setLoc(StartLoc);
19432   }
19433 
19434   // Iterators to find the current unresolved mapper expression.
19435   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
19436   bool UpdateUMIt = false;
19437   Expr *UnresolvedMapper = nullptr;
19438 
19439   bool HasHoldModifier =
19440       llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
19441 
19442   // Keep track of the mappable components and base declarations in this clause.
19443   // Each entry in the list is going to have a list of components associated. We
19444   // record each set of the components so that we can build the clause later on.
19445   // In the end we should have the same amount of declarations and component
19446   // lists.
19447 
19448   for (Expr *RE : MVLI.VarList) {
19449     assert(RE && "Null expr in omp to/from/map clause");
19450     SourceLocation ELoc = RE->getExprLoc();
19451 
19452     // Find the current unresolved mapper expression.
19453     if (UpdateUMIt && UMIt != UMEnd) {
19454       UMIt++;
19455       assert(
19456           UMIt != UMEnd &&
19457           "Expect the size of UnresolvedMappers to match with that of VarList");
19458     }
19459     UpdateUMIt = true;
19460     if (UMIt != UMEnd)
19461       UnresolvedMapper = *UMIt;
19462 
19463     const Expr *VE = RE->IgnoreParenLValueCasts();
19464 
19465     if (VE->isValueDependent() || VE->isTypeDependent() ||
19466         VE->isInstantiationDependent() ||
19467         VE->containsUnexpandedParameterPack()) {
19468       // Try to find the associated user-defined mapper.
19469       ExprResult ER = buildUserDefinedMapperRef(
19470           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19471           VE->getType().getCanonicalType(), UnresolvedMapper);
19472       if (ER.isInvalid())
19473         continue;
19474       MVLI.UDMapperList.push_back(ER.get());
19475       // We can only analyze this information once the missing information is
19476       // resolved.
19477       MVLI.ProcessedVarList.push_back(RE);
19478       continue;
19479     }
19480 
19481     Expr *SimpleExpr = RE->IgnoreParenCasts();
19482 
19483     if (!RE->isLValue()) {
19484       if (SemaRef.getLangOpts().OpenMP < 50) {
19485         SemaRef.Diag(
19486             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
19487             << RE->getSourceRange();
19488       } else {
19489         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19490             << getOpenMPClauseName(CKind) << RE->getSourceRange();
19491       }
19492       continue;
19493     }
19494 
19495     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
19496     ValueDecl *CurDeclaration = nullptr;
19497 
19498     // Obtain the array or member expression bases if required. Also, fill the
19499     // components array with all the components identified in the process.
19500     const Expr *BE =
19501         checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
19502                                      DSAS->getCurrentDirective(), NoDiagnose);
19503     if (!BE)
19504       continue;
19505 
19506     assert(!CurComponents.empty() &&
19507            "Invalid mappable expression information.");
19508 
19509     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
19510       // Add store "this" pointer to class in DSAStackTy for future checking
19511       DSAS->addMappedClassesQualTypes(TE->getType());
19512       // Try to find the associated user-defined mapper.
19513       ExprResult ER = buildUserDefinedMapperRef(
19514           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19515           VE->getType().getCanonicalType(), UnresolvedMapper);
19516       if (ER.isInvalid())
19517         continue;
19518       MVLI.UDMapperList.push_back(ER.get());
19519       // Skip restriction checking for variable or field declarations
19520       MVLI.ProcessedVarList.push_back(RE);
19521       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19522       MVLI.VarComponents.back().append(CurComponents.begin(),
19523                                        CurComponents.end());
19524       MVLI.VarBaseDeclarations.push_back(nullptr);
19525       continue;
19526     }
19527 
19528     // For the following checks, we rely on the base declaration which is
19529     // expected to be associated with the last component. The declaration is
19530     // expected to be a variable or a field (if 'this' is being mapped).
19531     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
19532     assert(CurDeclaration && "Null decl on map clause.");
19533     assert(
19534         CurDeclaration->isCanonicalDecl() &&
19535         "Expecting components to have associated only canonical declarations.");
19536 
19537     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
19538     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
19539 
19540     assert((VD || FD) && "Only variables or fields are expected here!");
19541     (void)FD;
19542 
19543     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
19544     // threadprivate variables cannot appear in a map clause.
19545     // OpenMP 4.5 [2.10.5, target update Construct]
19546     // threadprivate variables cannot appear in a from clause.
19547     if (VD && DSAS->isThreadPrivate(VD)) {
19548       if (NoDiagnose)
19549         continue;
19550       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19551       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
19552           << getOpenMPClauseName(CKind);
19553       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
19554       continue;
19555     }
19556 
19557     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19558     //  A list item cannot appear in both a map clause and a data-sharing
19559     //  attribute clause on the same construct.
19560 
19561     // Check conflicts with other map clause expressions. We check the conflicts
19562     // with the current construct separately from the enclosing data
19563     // environment, because the restrictions are different. We only have to
19564     // check conflicts across regions for the map clauses.
19565     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19566                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
19567       break;
19568     if (CKind == OMPC_map &&
19569         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
19570         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19571                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
19572       break;
19573 
19574     // OpenMP 4.5 [2.10.5, target update Construct]
19575     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19576     //  If the type of a list item is a reference to a type T then the type will
19577     //  be considered to be T for all purposes of this clause.
19578     auto I = llvm::find_if(
19579         CurComponents,
19580         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
19581           return MC.getAssociatedDeclaration();
19582         });
19583     assert(I != CurComponents.end() && "Null decl on map clause.");
19584     (void)I;
19585     QualType Type;
19586     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
19587     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
19588     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
19589     if (ASE) {
19590       Type = ASE->getType().getNonReferenceType();
19591     } else if (OASE) {
19592       QualType BaseType =
19593           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19594       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19595         Type = ATy->getElementType();
19596       else
19597         Type = BaseType->getPointeeType();
19598       Type = Type.getNonReferenceType();
19599     } else if (OAShE) {
19600       Type = OAShE->getBase()->getType()->getPointeeType();
19601     } else {
19602       Type = VE->getType();
19603     }
19604 
19605     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
19606     // A list item in a to or from clause must have a mappable type.
19607     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19608     //  A list item must have a mappable type.
19609     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
19610                            DSAS, Type, /*FullCheck=*/true))
19611       continue;
19612 
19613     if (CKind == OMPC_map) {
19614       // target enter data
19615       // OpenMP [2.10.2, Restrictions, p. 99]
19616       // A map-type must be specified in all map clauses and must be either
19617       // to or alloc.
19618       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
19619       if (DKind == OMPD_target_enter_data &&
19620           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19621         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19622             << (IsMapTypeImplicit ? 1 : 0)
19623             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19624             << getOpenMPDirectiveName(DKind);
19625         continue;
19626       }
19627 
19628       // target exit_data
19629       // OpenMP [2.10.3, Restrictions, p. 102]
19630       // A map-type must be specified in all map clauses and must be either
19631       // from, release, or delete.
19632       if (DKind == OMPD_target_exit_data &&
19633           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19634             MapType == OMPC_MAP_delete)) {
19635         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19636             << (IsMapTypeImplicit ? 1 : 0)
19637             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19638             << getOpenMPDirectiveName(DKind);
19639         continue;
19640       }
19641 
19642       // The 'ompx_hold' modifier is specifically intended to be used on a
19643       // 'target' or 'target data' directive to prevent data from being unmapped
19644       // during the associated statement.  It is not permitted on a 'target
19645       // enter data' or 'target exit data' directive, which have no associated
19646       // statement.
19647       if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
19648           HasHoldModifier) {
19649         SemaRef.Diag(StartLoc,
19650                      diag::err_omp_invalid_map_type_modifier_for_directive)
19651             << getOpenMPSimpleClauseTypeName(OMPC_map,
19652                                              OMPC_MAP_MODIFIER_ompx_hold)
19653             << getOpenMPDirectiveName(DKind);
19654         continue;
19655       }
19656 
19657       // target, target data
19658       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19659       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19660       // A map-type in a map clause must be to, from, tofrom or alloc
19661       if ((DKind == OMPD_target_data ||
19662            isOpenMPTargetExecutionDirective(DKind)) &&
19663           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19664             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19665         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19666             << (IsMapTypeImplicit ? 1 : 0)
19667             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19668             << getOpenMPDirectiveName(DKind);
19669         continue;
19670       }
19671 
19672       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19673       // A list item cannot appear in both a map clause and a data-sharing
19674       // attribute clause on the same construct
19675       //
19676       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19677       // A list item cannot appear in both a map clause and a data-sharing
19678       // attribute clause on the same construct unless the construct is a
19679       // combined construct.
19680       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19681                   isOpenMPTargetExecutionDirective(DKind)) ||
19682                  DKind == OMPD_target)) {
19683         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19684         if (isOpenMPPrivate(DVar.CKind)) {
19685           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19686               << getOpenMPClauseName(DVar.CKind)
19687               << getOpenMPClauseName(OMPC_map)
19688               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19689           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19690           continue;
19691         }
19692       }
19693     }
19694 
19695     // Try to find the associated user-defined mapper.
19696     ExprResult ER = buildUserDefinedMapperRef(
19697         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19698         Type.getCanonicalType(), UnresolvedMapper);
19699     if (ER.isInvalid())
19700       continue;
19701     MVLI.UDMapperList.push_back(ER.get());
19702 
19703     // Save the current expression.
19704     MVLI.ProcessedVarList.push_back(RE);
19705 
19706     // Store the components in the stack so that they can be used to check
19707     // against other clauses later on.
19708     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19709                                           /*WhereFoundClauseKind=*/OMPC_map);
19710 
19711     // Save the components and declaration to create the clause. For purposes of
19712     // the clause creation, any component list that has has base 'this' uses
19713     // null as base declaration.
19714     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19715     MVLI.VarComponents.back().append(CurComponents.begin(),
19716                                      CurComponents.end());
19717     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19718                                                            : CurDeclaration);
19719   }
19720 }
19721 
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,bool NoDiagnose,ArrayRef<Expr * > UnresolvedMappers)19722 OMPClause *Sema::ActOnOpenMPMapClause(
19723     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19724     ArrayRef<SourceLocation> MapTypeModifiersLoc,
19725     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19726     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19727     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19728     const OMPVarListLocTy &Locs, bool NoDiagnose,
19729     ArrayRef<Expr *> UnresolvedMappers) {
19730   OpenMPMapModifierKind Modifiers[] = {
19731       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19732       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19733       OMPC_MAP_MODIFIER_unknown};
19734   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19735 
19736   // Process map-type-modifiers, flag errors for duplicate modifiers.
19737   unsigned Count = 0;
19738   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19739     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19740         llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
19741       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19742       continue;
19743     }
19744     assert(Count < NumberOfOMPMapClauseModifiers &&
19745            "Modifiers exceed the allowed number of map type modifiers");
19746     Modifiers[Count] = MapTypeModifiers[I];
19747     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19748     ++Count;
19749   }
19750 
19751   MappableVarListInfo MVLI(VarList);
19752   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
19753                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
19754                               MapType, Modifiers, IsMapTypeImplicit,
19755                               NoDiagnose);
19756 
19757   // We need to produce a map clause even if we don't have variables so that
19758   // other diagnostics related with non-existing map clauses are accurate.
19759   return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19760                               MVLI.VarBaseDeclarations, MVLI.VarComponents,
19761                               MVLI.UDMapperList, Modifiers, ModifiersLoc,
19762                               MapperIdScopeSpec.getWithLocInContext(Context),
19763                               MapperId, MapType, IsMapTypeImplicit, MapLoc);
19764 }
19765 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)19766 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19767                                                TypeResult ParsedType) {
19768   assert(ParsedType.isUsable());
19769 
19770   QualType ReductionType = GetTypeFromParser(ParsedType.get());
19771   if (ReductionType.isNull())
19772     return QualType();
19773 
19774   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19775   // A type name in a declare reduction directive cannot be a function type, an
19776   // array type, a reference type, or a type qualified with const, volatile or
19777   // restrict.
19778   if (ReductionType.hasQualifiers()) {
19779     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19780     return QualType();
19781   }
19782 
19783   if (ReductionType->isFunctionType()) {
19784     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19785     return QualType();
19786   }
19787   if (ReductionType->isReferenceType()) {
19788     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19789     return QualType();
19790   }
19791   if (ReductionType->isArrayType()) {
19792     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19793     return QualType();
19794   }
19795   return ReductionType;
19796 }
19797 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)19798 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19799     Scope *S, DeclContext *DC, DeclarationName Name,
19800     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19801     AccessSpecifier AS, Decl *PrevDeclInScope) {
19802   SmallVector<Decl *, 8> Decls;
19803   Decls.reserve(ReductionTypes.size());
19804 
19805   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19806                       forRedeclarationInCurContext());
19807   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19808   // A reduction-identifier may not be re-declared in the current scope for the
19809   // same type or for a type that is compatible according to the base language
19810   // rules.
19811   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19812   OMPDeclareReductionDecl *PrevDRD = nullptr;
19813   bool InCompoundScope = true;
19814   if (S != nullptr) {
19815     // Find previous declaration with the same name not referenced in other
19816     // declarations.
19817     FunctionScopeInfo *ParentFn = getEnclosingFunction();
19818     InCompoundScope =
19819         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19820     LookupName(Lookup, S);
19821     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19822                          /*AllowInlineNamespace=*/false);
19823     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19824     LookupResult::Filter Filter = Lookup.makeFilter();
19825     while (Filter.hasNext()) {
19826       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19827       if (InCompoundScope) {
19828         auto I = UsedAsPrevious.find(PrevDecl);
19829         if (I == UsedAsPrevious.end())
19830           UsedAsPrevious[PrevDecl] = false;
19831         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19832           UsedAsPrevious[D] = true;
19833       }
19834       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19835           PrevDecl->getLocation();
19836     }
19837     Filter.done();
19838     if (InCompoundScope) {
19839       for (const auto &PrevData : UsedAsPrevious) {
19840         if (!PrevData.second) {
19841           PrevDRD = PrevData.first;
19842           break;
19843         }
19844       }
19845     }
19846   } else if (PrevDeclInScope != nullptr) {
19847     auto *PrevDRDInScope = PrevDRD =
19848         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19849     do {
19850       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19851           PrevDRDInScope->getLocation();
19852       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19853     } while (PrevDRDInScope != nullptr);
19854   }
19855   for (const auto &TyData : ReductionTypes) {
19856     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19857     bool Invalid = false;
19858     if (I != PreviousRedeclTypes.end()) {
19859       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19860           << TyData.first;
19861       Diag(I->second, diag::note_previous_definition);
19862       Invalid = true;
19863     }
19864     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19865     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19866                                                 Name, TyData.first, PrevDRD);
19867     DC->addDecl(DRD);
19868     DRD->setAccess(AS);
19869     Decls.push_back(DRD);
19870     if (Invalid)
19871       DRD->setInvalidDecl();
19872     else
19873       PrevDRD = DRD;
19874   }
19875 
19876   return DeclGroupPtrTy::make(
19877       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19878 }
19879 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)19880 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19881   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19882 
19883   // Enter new function scope.
19884   PushFunctionScope();
19885   setFunctionHasBranchProtectedScope();
19886   getCurFunction()->setHasOMPDeclareReductionCombiner();
19887 
19888   if (S != nullptr)
19889     PushDeclContext(S, DRD);
19890   else
19891     CurContext = DRD;
19892 
19893   PushExpressionEvaluationContext(
19894       ExpressionEvaluationContext::PotentiallyEvaluated);
19895 
19896   QualType ReductionType = DRD->getType();
19897   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19898   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19899   // uses semantics of argument handles by value, but it should be passed by
19900   // reference. C lang does not support references, so pass all parameters as
19901   // pointers.
19902   // Create 'T omp_in;' variable.
19903   VarDecl *OmpInParm =
19904       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19905   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19906   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19907   // uses semantics of argument handles by value, but it should be passed by
19908   // reference. C lang does not support references, so pass all parameters as
19909   // pointers.
19910   // Create 'T omp_out;' variable.
19911   VarDecl *OmpOutParm =
19912       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19913   if (S != nullptr) {
19914     PushOnScopeChains(OmpInParm, S);
19915     PushOnScopeChains(OmpOutParm, S);
19916   } else {
19917     DRD->addDecl(OmpInParm);
19918     DRD->addDecl(OmpOutParm);
19919   }
19920   Expr *InE =
19921       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19922   Expr *OutE =
19923       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19924   DRD->setCombinerData(InE, OutE);
19925 }
19926 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)19927 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19928   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19929   DiscardCleanupsInEvaluationContext();
19930   PopExpressionEvaluationContext();
19931 
19932   PopDeclContext();
19933   PopFunctionScopeInfo();
19934 
19935   if (Combiner != nullptr)
19936     DRD->setCombiner(Combiner);
19937   else
19938     DRD->setInvalidDecl();
19939 }
19940 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)19941 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19942   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19943 
19944   // Enter new function scope.
19945   PushFunctionScope();
19946   setFunctionHasBranchProtectedScope();
19947 
19948   if (S != nullptr)
19949     PushDeclContext(S, DRD);
19950   else
19951     CurContext = DRD;
19952 
19953   PushExpressionEvaluationContext(
19954       ExpressionEvaluationContext::PotentiallyEvaluated);
19955 
19956   QualType ReductionType = DRD->getType();
19957   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19958   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19959   // uses semantics of argument handles by value, but it should be passed by
19960   // reference. C lang does not support references, so pass all parameters as
19961   // pointers.
19962   // Create 'T omp_priv;' variable.
19963   VarDecl *OmpPrivParm =
19964       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19965   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19966   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19967   // uses semantics of argument handles by value, but it should be passed by
19968   // reference. C lang does not support references, so pass all parameters as
19969   // pointers.
19970   // Create 'T omp_orig;' variable.
19971   VarDecl *OmpOrigParm =
19972       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19973   if (S != nullptr) {
19974     PushOnScopeChains(OmpPrivParm, S);
19975     PushOnScopeChains(OmpOrigParm, S);
19976   } else {
19977     DRD->addDecl(OmpPrivParm);
19978     DRD->addDecl(OmpOrigParm);
19979   }
19980   Expr *OrigE =
19981       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19982   Expr *PrivE =
19983       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19984   DRD->setInitializerData(OrigE, PrivE);
19985   return OmpPrivParm;
19986 }
19987 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)19988 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19989                                                      VarDecl *OmpPrivParm) {
19990   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19991   DiscardCleanupsInEvaluationContext();
19992   PopExpressionEvaluationContext();
19993 
19994   PopDeclContext();
19995   PopFunctionScopeInfo();
19996 
19997   if (Initializer != nullptr) {
19998     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19999   } else if (OmpPrivParm->hasInit()) {
20000     DRD->setInitializer(OmpPrivParm->getInit(),
20001                         OmpPrivParm->isDirectInit()
20002                             ? OMPDeclareReductionDecl::DirectInit
20003                             : OMPDeclareReductionDecl::CopyInit);
20004   } else {
20005     DRD->setInvalidDecl();
20006   }
20007 }
20008 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)20009 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
20010     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
20011   for (Decl *D : DeclReductions.get()) {
20012     if (IsValid) {
20013       if (S)
20014         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
20015                           /*AddToContext=*/false);
20016     } else {
20017       D->setInvalidDecl();
20018     }
20019   }
20020   return DeclReductions;
20021 }
20022 
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)20023 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
20024   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
20025   QualType T = TInfo->getType();
20026   if (D.isInvalidType())
20027     return true;
20028 
20029   if (getLangOpts().CPlusPlus) {
20030     // Check that there are no default arguments (C++ only).
20031     CheckExtraCXXDefaultArguments(D);
20032   }
20033 
20034   return CreateParsedType(T, TInfo);
20035 }
20036 
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)20037 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
20038                                             TypeResult ParsedType) {
20039   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
20040 
20041   QualType MapperType = GetTypeFromParser(ParsedType.get());
20042   assert(!MapperType.isNull() && "Expect valid mapper type");
20043 
20044   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
20045   //  The type must be of struct, union or class type in C and C++
20046   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
20047     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
20048     return QualType();
20049   }
20050   return MapperType;
20051 }
20052 
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)20053 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
20054     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
20055     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
20056     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
20057   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
20058                       forRedeclarationInCurContext());
20059   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
20060   //  A mapper-identifier may not be redeclared in the current scope for the
20061   //  same type or for a type that is compatible according to the base language
20062   //  rules.
20063   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
20064   OMPDeclareMapperDecl *PrevDMD = nullptr;
20065   bool InCompoundScope = true;
20066   if (S != nullptr) {
20067     // Find previous declaration with the same name not referenced in other
20068     // declarations.
20069     FunctionScopeInfo *ParentFn = getEnclosingFunction();
20070     InCompoundScope =
20071         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
20072     LookupName(Lookup, S);
20073     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
20074                          /*AllowInlineNamespace=*/false);
20075     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
20076     LookupResult::Filter Filter = Lookup.makeFilter();
20077     while (Filter.hasNext()) {
20078       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
20079       if (InCompoundScope) {
20080         auto I = UsedAsPrevious.find(PrevDecl);
20081         if (I == UsedAsPrevious.end())
20082           UsedAsPrevious[PrevDecl] = false;
20083         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
20084           UsedAsPrevious[D] = true;
20085       }
20086       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
20087           PrevDecl->getLocation();
20088     }
20089     Filter.done();
20090     if (InCompoundScope) {
20091       for (const auto &PrevData : UsedAsPrevious) {
20092         if (!PrevData.second) {
20093           PrevDMD = PrevData.first;
20094           break;
20095         }
20096       }
20097     }
20098   } else if (PrevDeclInScope) {
20099     auto *PrevDMDInScope = PrevDMD =
20100         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
20101     do {
20102       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
20103           PrevDMDInScope->getLocation();
20104       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
20105     } while (PrevDMDInScope != nullptr);
20106   }
20107   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
20108   bool Invalid = false;
20109   if (I != PreviousRedeclTypes.end()) {
20110     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
20111         << MapperType << Name;
20112     Diag(I->second, diag::note_previous_definition);
20113     Invalid = true;
20114   }
20115   // Build expressions for implicit maps of data members with 'default'
20116   // mappers.
20117   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
20118                                                   Clauses.end());
20119   if (LangOpts.OpenMP >= 50)
20120     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
20121   auto *DMD =
20122       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
20123                                    ClausesWithImplicit, PrevDMD);
20124   if (S)
20125     PushOnScopeChains(DMD, S);
20126   else
20127     DC->addDecl(DMD);
20128   DMD->setAccess(AS);
20129   if (Invalid)
20130     DMD->setInvalidDecl();
20131 
20132   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
20133   VD->setDeclContext(DMD);
20134   VD->setLexicalDeclContext(DMD);
20135   DMD->addDecl(VD);
20136   DMD->setMapperVarRef(MapperVarRef);
20137 
20138   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
20139 }
20140 
20141 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)20142 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
20143                                                SourceLocation StartLoc,
20144                                                DeclarationName VN) {
20145   TypeSourceInfo *TInfo =
20146       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
20147   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
20148                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
20149                              MapperType, TInfo, SC_None);
20150   if (S)
20151     PushOnScopeChains(VD, S, /*AddToContext=*/false);
20152   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
20153   DSAStack->addDeclareMapperVarRef(E);
20154   return E;
20155 }
20156 
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const20157 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
20158   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
20159   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
20160   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
20161     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
20162       return true;
20163     if (VD->isUsableInConstantExpressions(Context))
20164       return true;
20165     return false;
20166   }
20167   return true;
20168 }
20169 
getOpenMPDeclareMapperVarName() const20170 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
20171   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
20172   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
20173 }
20174 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20175 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
20176                                            SourceLocation StartLoc,
20177                                            SourceLocation LParenLoc,
20178                                            SourceLocation EndLoc) {
20179   Expr *ValExpr = NumTeams;
20180   Stmt *HelperValStmt = nullptr;
20181 
20182   // OpenMP [teams Constrcut, Restrictions]
20183   // The num_teams expression must evaluate to a positive integer value.
20184   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
20185                                  /*StrictlyPositive=*/true))
20186     return nullptr;
20187 
20188   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20189   OpenMPDirectiveKind CaptureRegion =
20190       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
20191   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20192     ValExpr = MakeFullExpr(ValExpr).get();
20193     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20194     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20195     HelperValStmt = buildPreInits(Context, Captures);
20196   }
20197 
20198   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
20199                                          StartLoc, LParenLoc, EndLoc);
20200 }
20201 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20202 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
20203                                               SourceLocation StartLoc,
20204                                               SourceLocation LParenLoc,
20205                                               SourceLocation EndLoc) {
20206   Expr *ValExpr = ThreadLimit;
20207   Stmt *HelperValStmt = nullptr;
20208 
20209   // OpenMP [teams Constrcut, Restrictions]
20210   // The thread_limit expression must evaluate to a positive integer value.
20211   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
20212                                  /*StrictlyPositive=*/true))
20213     return nullptr;
20214 
20215   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20216   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
20217       DKind, OMPC_thread_limit, LangOpts.OpenMP);
20218   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20219     ValExpr = MakeFullExpr(ValExpr).get();
20220     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20221     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20222     HelperValStmt = buildPreInits(Context, Captures);
20223   }
20224 
20225   return new (Context) OMPThreadLimitClause(
20226       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
20227 }
20228 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20229 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
20230                                            SourceLocation StartLoc,
20231                                            SourceLocation LParenLoc,
20232                                            SourceLocation EndLoc) {
20233   Expr *ValExpr = Priority;
20234   Stmt *HelperValStmt = nullptr;
20235   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20236 
20237   // OpenMP [2.9.1, task Constrcut]
20238   // The priority-value is a non-negative numerical scalar expression.
20239   if (!isNonNegativeIntegerValue(
20240           ValExpr, *this, OMPC_priority,
20241           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
20242           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20243     return nullptr;
20244 
20245   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
20246                                          StartLoc, LParenLoc, EndLoc);
20247 }
20248 
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20249 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
20250                                             SourceLocation StartLoc,
20251                                             SourceLocation LParenLoc,
20252                                             SourceLocation EndLoc) {
20253   Expr *ValExpr = Grainsize;
20254   Stmt *HelperValStmt = nullptr;
20255   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20256 
20257   // OpenMP [2.9.2, taskloop Constrcut]
20258   // The parameter of the grainsize clause must be a positive integer
20259   // expression.
20260   if (!isNonNegativeIntegerValue(
20261           ValExpr, *this, OMPC_grainsize,
20262           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20263           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20264     return nullptr;
20265 
20266   return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
20267                                           StartLoc, LParenLoc, EndLoc);
20268 }
20269 
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20270 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
20271                                            SourceLocation StartLoc,
20272                                            SourceLocation LParenLoc,
20273                                            SourceLocation EndLoc) {
20274   Expr *ValExpr = NumTasks;
20275   Stmt *HelperValStmt = nullptr;
20276   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20277 
20278   // OpenMP [2.9.2, taskloop Constrcut]
20279   // The parameter of the num_tasks clause must be a positive integer
20280   // expression.
20281   if (!isNonNegativeIntegerValue(
20282           ValExpr, *this, OMPC_num_tasks,
20283           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20284           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20285     return nullptr;
20286 
20287   return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
20288                                          StartLoc, LParenLoc, EndLoc);
20289 }
20290 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20291 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
20292                                        SourceLocation LParenLoc,
20293                                        SourceLocation EndLoc) {
20294   // OpenMP [2.13.2, critical construct, Description]
20295   // ... where hint-expression is an integer constant expression that evaluates
20296   // to a valid lock hint.
20297   ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
20298   if (HintExpr.isInvalid())
20299     return nullptr;
20300   return new (Context)
20301       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
20302 }
20303 
20304 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)20305 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
20306                                 DSAStackTy *Stack) {
20307   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
20308   if (!OMPEventHandleT.isNull())
20309     return true;
20310   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
20311   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20312   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20313     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
20314     return false;
20315   }
20316   Stack->setOMPEventHandleT(PT.get());
20317   return true;
20318 }
20319 
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20320 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
20321                                          SourceLocation LParenLoc,
20322                                          SourceLocation EndLoc) {
20323   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
20324       !Evt->isInstantiationDependent() &&
20325       !Evt->containsUnexpandedParameterPack()) {
20326     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
20327       return nullptr;
20328     // OpenMP 5.0, 2.10.1 task Construct.
20329     // event-handle is a variable of the omp_event_handle_t type.
20330     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
20331     if (!Ref) {
20332       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20333           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20334       return nullptr;
20335     }
20336     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
20337     if (!VD) {
20338       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20339           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20340       return nullptr;
20341     }
20342     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
20343                                         VD->getType()) ||
20344         VD->getType().isConstant(Context)) {
20345       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20346           << "omp_event_handle_t" << 1 << VD->getType()
20347           << Evt->getSourceRange();
20348       return nullptr;
20349     }
20350     // OpenMP 5.0, 2.10.1 task Construct
20351     // [detach clause]... The event-handle will be considered as if it was
20352     // specified on a firstprivate clause.
20353     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
20354     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
20355         DVar.RefExpr) {
20356       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
20357           << getOpenMPClauseName(DVar.CKind)
20358           << getOpenMPClauseName(OMPC_firstprivate);
20359       reportOriginalDsa(*this, DSAStack, VD, DVar);
20360       return nullptr;
20361     }
20362   }
20363 
20364   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
20365 }
20366 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)20367 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
20368     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
20369     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
20370     SourceLocation EndLoc) {
20371   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
20372     std::string Values;
20373     Values += "'";
20374     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
20375     Values += "'";
20376     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20377         << Values << getOpenMPClauseName(OMPC_dist_schedule);
20378     return nullptr;
20379   }
20380   Expr *ValExpr = ChunkSize;
20381   Stmt *HelperValStmt = nullptr;
20382   if (ChunkSize) {
20383     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
20384         !ChunkSize->isInstantiationDependent() &&
20385         !ChunkSize->containsUnexpandedParameterPack()) {
20386       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
20387       ExprResult Val =
20388           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
20389       if (Val.isInvalid())
20390         return nullptr;
20391 
20392       ValExpr = Val.get();
20393 
20394       // OpenMP [2.7.1, Restrictions]
20395       //  chunk_size must be a loop invariant integer expression with a positive
20396       //  value.
20397       if (Optional<llvm::APSInt> Result =
20398               ValExpr->getIntegerConstantExpr(Context)) {
20399         if (Result->isSigned() && !Result->isStrictlyPositive()) {
20400           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
20401               << "dist_schedule" << ChunkSize->getSourceRange();
20402           return nullptr;
20403         }
20404       } else if (getOpenMPCaptureRegionForClause(
20405                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
20406                      LangOpts.OpenMP) != OMPD_unknown &&
20407                  !CurContext->isDependentContext()) {
20408         ValExpr = MakeFullExpr(ValExpr).get();
20409         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20410         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20411         HelperValStmt = buildPreInits(Context, Captures);
20412       }
20413     }
20414   }
20415 
20416   return new (Context)
20417       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
20418                             Kind, ValExpr, HelperValStmt);
20419 }
20420 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)20421 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
20422     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
20423     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
20424     SourceLocation KindLoc, SourceLocation EndLoc) {
20425   if (getLangOpts().OpenMP < 50) {
20426     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
20427         Kind != OMPC_DEFAULTMAP_scalar) {
20428       std::string Value;
20429       SourceLocation Loc;
20430       Value += "'";
20431       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
20432         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20433                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
20434         Loc = MLoc;
20435       } else {
20436         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20437                                                OMPC_DEFAULTMAP_scalar);
20438         Loc = KindLoc;
20439       }
20440       Value += "'";
20441       Diag(Loc, diag::err_omp_unexpected_clause_value)
20442           << Value << getOpenMPClauseName(OMPC_defaultmap);
20443       return nullptr;
20444     }
20445   } else {
20446     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
20447     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
20448                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
20449     if (!isDefaultmapKind || !isDefaultmapModifier) {
20450       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
20451       if (LangOpts.OpenMP == 50) {
20452         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
20453                                   "'firstprivate', 'none', 'default'";
20454         if (!isDefaultmapKind && isDefaultmapModifier) {
20455           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20456               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20457         } else if (isDefaultmapKind && !isDefaultmapModifier) {
20458           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20459               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20460         } else {
20461           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20462               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20463           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20464               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20465         }
20466       } else {
20467         StringRef ModifierValue =
20468             "'alloc', 'from', 'to', 'tofrom', "
20469             "'firstprivate', 'none', 'default', 'present'";
20470         if (!isDefaultmapKind && isDefaultmapModifier) {
20471           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20472               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20473         } else if (isDefaultmapKind && !isDefaultmapModifier) {
20474           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20475               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20476         } else {
20477           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20478               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20479           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20480               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20481         }
20482       }
20483       return nullptr;
20484     }
20485 
20486     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
20487     //  At most one defaultmap clause for each category can appear on the
20488     //  directive.
20489     if (DSAStack->checkDefaultmapCategory(Kind)) {
20490       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
20491       return nullptr;
20492     }
20493   }
20494   if (Kind == OMPC_DEFAULTMAP_unknown) {
20495     // Variable category is not specified - mark all categories.
20496     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
20497     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
20498     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
20499   } else {
20500     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
20501   }
20502 
20503   return new (Context)
20504       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
20505 }
20506 
ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20507 bool Sema::ActOnStartOpenMPDeclareTargetContext(
20508     DeclareTargetContextInfo &DTCI) {
20509   DeclContext *CurLexicalContext = getCurLexicalContext();
20510   if (!CurLexicalContext->isFileContext() &&
20511       !CurLexicalContext->isExternCContext() &&
20512       !CurLexicalContext->isExternCXXContext() &&
20513       !isa<CXXRecordDecl>(CurLexicalContext) &&
20514       !isa<ClassTemplateDecl>(CurLexicalContext) &&
20515       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
20516       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
20517     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
20518     return false;
20519   }
20520   DeclareTargetNesting.push_back(DTCI);
20521   return true;
20522 }
20523 
20524 const Sema::DeclareTargetContextInfo
ActOnOpenMPEndDeclareTargetDirective()20525 Sema::ActOnOpenMPEndDeclareTargetDirective() {
20526   assert(!DeclareTargetNesting.empty() &&
20527          "check isInOpenMPDeclareTargetContext() first!");
20528   return DeclareTargetNesting.pop_back_val();
20529 }
20530 
ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20531 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
20532     DeclareTargetContextInfo &DTCI) {
20533   for (auto &It : DTCI.ExplicitlyMapped)
20534     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT,
20535                                  DTCI.DT);
20536 }
20537 
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)20538 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
20539                                                CXXScopeSpec &ScopeSpec,
20540                                                const DeclarationNameInfo &Id) {
20541   LookupResult Lookup(*this, Id, LookupOrdinaryName);
20542   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
20543 
20544   if (Lookup.isAmbiguous())
20545     return nullptr;
20546   Lookup.suppressDiagnostics();
20547 
20548   if (!Lookup.isSingleResult()) {
20549     VarOrFuncDeclFilterCCC CCC(*this);
20550     if (TypoCorrection Corrected =
20551             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
20552                         CTK_ErrorRecovery)) {
20553       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
20554                                   << Id.getName());
20555       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
20556       return nullptr;
20557     }
20558 
20559     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
20560     return nullptr;
20561   }
20562 
20563   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
20564   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
20565       !isa<FunctionTemplateDecl>(ND)) {
20566     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
20567     return nullptr;
20568   }
20569   return ND;
20570 }
20571 
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)20572 void Sema::ActOnOpenMPDeclareTargetName(
20573     NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
20574     OMPDeclareTargetDeclAttr::DevTypeTy DT) {
20575   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
20576           isa<FunctionTemplateDecl>(ND)) &&
20577          "Expected variable, function or function template.");
20578 
20579   // Diagnose marking after use as it may lead to incorrect diagnosis and
20580   // codegen.
20581   if (LangOpts.OpenMP >= 50 &&
20582       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
20583     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
20584 
20585   // Explicit declare target lists have precedence.
20586   const unsigned Level = -1;
20587 
20588   auto *VD = cast<ValueDecl>(ND);
20589   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20590       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20591   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT &&
20592       ActiveAttr.getValue()->getLevel() == Level) {
20593     Diag(Loc, diag::err_omp_device_type_mismatch)
20594         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
20595         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
20596                ActiveAttr.getValue()->getDevType());
20597     return;
20598   }
20599   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
20600       ActiveAttr.getValue()->getLevel() == Level) {
20601     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
20602     return;
20603   }
20604 
20605   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
20606     return;
20607 
20608   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level,
20609                                                      SourceRange(Loc, Loc));
20610   ND->addAttr(A);
20611   if (ASTMutationListener *ML = Context.getASTMutationListener())
20612     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
20613   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
20614 }
20615 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)20616 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
20617                                      Sema &SemaRef, Decl *D) {
20618   if (!D || !isa<VarDecl>(D))
20619     return;
20620   auto *VD = cast<VarDecl>(D);
20621   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
20622       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
20623   if (SemaRef.LangOpts.OpenMP >= 50 &&
20624       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
20625        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
20626       VD->hasGlobalStorage()) {
20627     if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
20628       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
20629       // If a lambda declaration and definition appears between a
20630       // declare target directive and the matching end declare target
20631       // directive, all variables that are captured by the lambda
20632       // expression must also appear in a to clause.
20633       SemaRef.Diag(VD->getLocation(),
20634                    diag::err_omp_lambda_capture_in_declare_target_not_to);
20635       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
20636           << VD << 0 << SR;
20637       return;
20638     }
20639   }
20640   if (MapTy.hasValue())
20641     return;
20642   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
20643   SemaRef.Diag(SL, diag::note_used_here) << SR;
20644 }
20645 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)20646 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
20647                                    Sema &SemaRef, DSAStackTy *Stack,
20648                                    ValueDecl *VD) {
20649   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20650          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20651                            /*FullCheck=*/false);
20652 }
20653 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)20654 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20655                                             SourceLocation IdLoc) {
20656   if (!D || D->isInvalidDecl())
20657     return;
20658   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20659   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20660   if (auto *VD = dyn_cast<VarDecl>(D)) {
20661     // Only global variables can be marked as declare target.
20662     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20663         !VD->isStaticDataMember())
20664       return;
20665     // 2.10.6: threadprivate variable cannot appear in a declare target
20666     // directive.
20667     if (DSAStack->isThreadPrivate(VD)) {
20668       Diag(SL, diag::err_omp_threadprivate_in_target);
20669       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
20670       return;
20671     }
20672   }
20673   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20674     D = FTD->getTemplatedDecl();
20675   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20676     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20677         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20678     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20679       Diag(IdLoc, diag::err_omp_function_in_link_clause);
20680       Diag(FD->getLocation(), diag::note_defined_here) << FD;
20681       return;
20682     }
20683   }
20684   if (auto *VD = dyn_cast<ValueDecl>(D)) {
20685     // Problem if any with var declared with incomplete type will be reported
20686     // as normal, so no need to check it here.
20687     if ((E || !VD->getType()->isIncompleteType()) &&
20688         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
20689       return;
20690     if (!E && isInOpenMPDeclareTargetContext()) {
20691       // Checking declaration inside declare target region.
20692       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20693           isa<FunctionTemplateDecl>(D)) {
20694         llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20695             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20696         unsigned Level = DeclareTargetNesting.size();
20697         if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
20698           return;
20699         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
20700         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20701             Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level,
20702             SourceRange(DTCI.Loc, DTCI.Loc));
20703         D->addAttr(A);
20704         if (ASTMutationListener *ML = Context.getASTMutationListener())
20705           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20706       }
20707       return;
20708     }
20709   }
20710   if (!E)
20711     return;
20712   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20713 }
20714 
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20715 OMPClause *Sema::ActOnOpenMPToClause(
20716     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20717     ArrayRef<SourceLocation> MotionModifiersLoc,
20718     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20719     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20720     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20721   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20722                                           OMPC_MOTION_MODIFIER_unknown};
20723   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20724 
20725   // Process motion-modifiers, flag errors for duplicate modifiers.
20726   unsigned Count = 0;
20727   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20728     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20729         llvm::is_contained(Modifiers, MotionModifiers[I])) {
20730       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20731       continue;
20732     }
20733     assert(Count < NumberOfOMPMotionModifiers &&
20734            "Modifiers exceed the allowed number of motion modifiers");
20735     Modifiers[Count] = MotionModifiers[I];
20736     ModifiersLoc[Count] = MotionModifiersLoc[I];
20737     ++Count;
20738   }
20739 
20740   MappableVarListInfo MVLI(VarList);
20741   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
20742                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
20743   if (MVLI.ProcessedVarList.empty())
20744     return nullptr;
20745 
20746   return OMPToClause::Create(
20747       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20748       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20749       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20750 }
20751 
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20752 OMPClause *Sema::ActOnOpenMPFromClause(
20753     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20754     ArrayRef<SourceLocation> MotionModifiersLoc,
20755     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20756     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20757     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20758   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20759                                           OMPC_MOTION_MODIFIER_unknown};
20760   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20761 
20762   // Process motion-modifiers, flag errors for duplicate modifiers.
20763   unsigned Count = 0;
20764   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20765     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20766         llvm::is_contained(Modifiers, MotionModifiers[I])) {
20767       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20768       continue;
20769     }
20770     assert(Count < NumberOfOMPMotionModifiers &&
20771            "Modifiers exceed the allowed number of motion modifiers");
20772     Modifiers[Count] = MotionModifiers[I];
20773     ModifiersLoc[Count] = MotionModifiersLoc[I];
20774     ++Count;
20775   }
20776 
20777   MappableVarListInfo MVLI(VarList);
20778   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
20779                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
20780   if (MVLI.ProcessedVarList.empty())
20781     return nullptr;
20782 
20783   return OMPFromClause::Create(
20784       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20785       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20786       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20787 }
20788 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20789 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20790                                                const OMPVarListLocTy &Locs) {
20791   MappableVarListInfo MVLI(VarList);
20792   SmallVector<Expr *, 8> PrivateCopies;
20793   SmallVector<Expr *, 8> Inits;
20794 
20795   for (Expr *RefExpr : VarList) {
20796     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
20797     SourceLocation ELoc;
20798     SourceRange ERange;
20799     Expr *SimpleRefExpr = RefExpr;
20800     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20801     if (Res.second) {
20802       // It will be analyzed later.
20803       MVLI.ProcessedVarList.push_back(RefExpr);
20804       PrivateCopies.push_back(nullptr);
20805       Inits.push_back(nullptr);
20806     }
20807     ValueDecl *D = Res.first;
20808     if (!D)
20809       continue;
20810 
20811     QualType Type = D->getType();
20812     Type = Type.getNonReferenceType().getUnqualifiedType();
20813 
20814     auto *VD = dyn_cast<VarDecl>(D);
20815 
20816     // Item should be a pointer or reference to pointer.
20817     if (!Type->isPointerType()) {
20818       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20819           << 0 << RefExpr->getSourceRange();
20820       continue;
20821     }
20822 
20823     // Build the private variable and the expression that refers to it.
20824     auto VDPrivate =
20825         buildVarDecl(*this, ELoc, Type, D->getName(),
20826                      D->hasAttrs() ? &D->getAttrs() : nullptr,
20827                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20828     if (VDPrivate->isInvalidDecl())
20829       continue;
20830 
20831     CurContext->addDecl(VDPrivate);
20832     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20833         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20834 
20835     // Add temporary variable to initialize the private copy of the pointer.
20836     VarDecl *VDInit =
20837         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20838     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20839         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20840     AddInitializerToDecl(VDPrivate,
20841                          DefaultLvalueConversion(VDInitRefExpr).get(),
20842                          /*DirectInit=*/false);
20843 
20844     // If required, build a capture to implement the privatization initialized
20845     // with the current list item value.
20846     DeclRefExpr *Ref = nullptr;
20847     if (!VD)
20848       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20849     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20850     PrivateCopies.push_back(VDPrivateRefExpr);
20851     Inits.push_back(VDInitRefExpr);
20852 
20853     // We need to add a data sharing attribute for this variable to make sure it
20854     // is correctly captured. A variable that shows up in a use_device_ptr has
20855     // similar properties of a first private variable.
20856     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20857 
20858     // Create a mappable component for the list item. List items in this clause
20859     // only need a component.
20860     MVLI.VarBaseDeclarations.push_back(D);
20861     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20862     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20863                                            /*IsNonContiguous=*/false);
20864   }
20865 
20866   if (MVLI.ProcessedVarList.empty())
20867     return nullptr;
20868 
20869   return OMPUseDevicePtrClause::Create(
20870       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20871       MVLI.VarBaseDeclarations, MVLI.VarComponents);
20872 }
20873 
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20874 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20875                                                 const OMPVarListLocTy &Locs) {
20876   MappableVarListInfo MVLI(VarList);
20877 
20878   for (Expr *RefExpr : VarList) {
20879     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
20880     SourceLocation ELoc;
20881     SourceRange ERange;
20882     Expr *SimpleRefExpr = RefExpr;
20883     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20884                               /*AllowArraySection=*/true);
20885     if (Res.second) {
20886       // It will be analyzed later.
20887       MVLI.ProcessedVarList.push_back(RefExpr);
20888     }
20889     ValueDecl *D = Res.first;
20890     if (!D)
20891       continue;
20892     auto *VD = dyn_cast<VarDecl>(D);
20893 
20894     // If required, build a capture to implement the privatization initialized
20895     // with the current list item value.
20896     DeclRefExpr *Ref = nullptr;
20897     if (!VD)
20898       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20899     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20900 
20901     // We need to add a data sharing attribute for this variable to make sure it
20902     // is correctly captured. A variable that shows up in a use_device_addr has
20903     // similar properties of a first private variable.
20904     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20905 
20906     // Create a mappable component for the list item. List items in this clause
20907     // only need a component.
20908     MVLI.VarBaseDeclarations.push_back(D);
20909     MVLI.VarComponents.emplace_back();
20910     Expr *Component = SimpleRefExpr;
20911     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20912                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20913       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20914     MVLI.VarComponents.back().emplace_back(Component, D,
20915                                            /*IsNonContiguous=*/false);
20916   }
20917 
20918   if (MVLI.ProcessedVarList.empty())
20919     return nullptr;
20920 
20921   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20922                                         MVLI.VarBaseDeclarations,
20923                                         MVLI.VarComponents);
20924 }
20925 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20926 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20927                                               const OMPVarListLocTy &Locs) {
20928   MappableVarListInfo MVLI(VarList);
20929   for (Expr *RefExpr : VarList) {
20930     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
20931     SourceLocation ELoc;
20932     SourceRange ERange;
20933     Expr *SimpleRefExpr = RefExpr;
20934     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20935     if (Res.second) {
20936       // It will be analyzed later.
20937       MVLI.ProcessedVarList.push_back(RefExpr);
20938     }
20939     ValueDecl *D = Res.first;
20940     if (!D)
20941       continue;
20942 
20943     QualType Type = D->getType();
20944     // item should be a pointer or array or reference to pointer or array
20945     if (!Type.getNonReferenceType()->isPointerType() &&
20946         !Type.getNonReferenceType()->isArrayType()) {
20947       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20948           << 0 << RefExpr->getSourceRange();
20949       continue;
20950     }
20951 
20952     // Check if the declaration in the clause does not show up in any data
20953     // sharing attribute.
20954     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20955     if (isOpenMPPrivate(DVar.CKind)) {
20956       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20957           << getOpenMPClauseName(DVar.CKind)
20958           << getOpenMPClauseName(OMPC_is_device_ptr)
20959           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20960       reportOriginalDsa(*this, DSAStack, D, DVar);
20961       continue;
20962     }
20963 
20964     const Expr *ConflictExpr;
20965     if (DSAStack->checkMappableExprComponentListsForDecl(
20966             D, /*CurrentRegionOnly=*/true,
20967             [&ConflictExpr](
20968                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20969                 OpenMPClauseKind) -> bool {
20970               ConflictExpr = R.front().getAssociatedExpression();
20971               return true;
20972             })) {
20973       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20974       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20975           << ConflictExpr->getSourceRange();
20976       continue;
20977     }
20978 
20979     // Store the components in the stack so that they can be used to check
20980     // against other clauses later on.
20981     OMPClauseMappableExprCommon::MappableComponent MC(
20982         SimpleRefExpr, D, /*IsNonContiguous=*/false);
20983     DSAStack->addMappableExpressionComponents(
20984         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20985 
20986     // Record the expression we've just processed.
20987     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20988 
20989     // Create a mappable component for the list item. List items in this clause
20990     // only need a component. We use a null declaration to signal fields in
20991     // 'this'.
20992     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
20993             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
20994            "Unexpected device pointer expression!");
20995     MVLI.VarBaseDeclarations.push_back(
20996         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20997     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20998     MVLI.VarComponents.back().push_back(MC);
20999   }
21000 
21001   if (MVLI.ProcessedVarList.empty())
21002     return nullptr;
21003 
21004   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
21005                                       MVLI.VarBaseDeclarations,
21006                                       MVLI.VarComponents);
21007 }
21008 
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)21009 OMPClause *Sema::ActOnOpenMPAllocateClause(
21010     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
21011     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
21012   if (Allocator) {
21013     // OpenMP [2.11.4 allocate Clause, Description]
21014     // allocator is an expression of omp_allocator_handle_t type.
21015     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
21016       return nullptr;
21017 
21018     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
21019     if (AllocatorRes.isInvalid())
21020       return nullptr;
21021     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
21022                                              DSAStack->getOMPAllocatorHandleT(),
21023                                              Sema::AA_Initializing,
21024                                              /*AllowExplicit=*/true);
21025     if (AllocatorRes.isInvalid())
21026       return nullptr;
21027     Allocator = AllocatorRes.get();
21028   } else {
21029     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
21030     // allocate clauses that appear on a target construct or on constructs in a
21031     // target region must specify an allocator expression unless a requires
21032     // directive with the dynamic_allocators clause is present in the same
21033     // compilation unit.
21034     if (LangOpts.OpenMPIsDevice &&
21035         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
21036       targetDiag(StartLoc, diag::err_expected_allocator_expression);
21037   }
21038   // Analyze and build list of variables.
21039   SmallVector<Expr *, 8> Vars;
21040   for (Expr *RefExpr : VarList) {
21041     assert(RefExpr && "NULL expr in OpenMP private clause.");
21042     SourceLocation ELoc;
21043     SourceRange ERange;
21044     Expr *SimpleRefExpr = RefExpr;
21045     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
21046     if (Res.second) {
21047       // It will be analyzed later.
21048       Vars.push_back(RefExpr);
21049     }
21050     ValueDecl *D = Res.first;
21051     if (!D)
21052       continue;
21053 
21054     auto *VD = dyn_cast<VarDecl>(D);
21055     DeclRefExpr *Ref = nullptr;
21056     if (!VD && !CurContext->isDependentContext())
21057       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
21058     Vars.push_back((VD || CurContext->isDependentContext())
21059                        ? RefExpr->IgnoreParens()
21060                        : Ref);
21061   }
21062 
21063   if (Vars.empty())
21064     return nullptr;
21065 
21066   if (Allocator)
21067     DSAStack->addInnerAllocatorExpr(Allocator);
21068   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
21069                                    ColonLoc, EndLoc, Vars);
21070 }
21071 
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)21072 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
21073                                               SourceLocation StartLoc,
21074                                               SourceLocation LParenLoc,
21075                                               SourceLocation EndLoc) {
21076   SmallVector<Expr *, 8> Vars;
21077   for (Expr *RefExpr : VarList) {
21078     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
21079     SourceLocation ELoc;
21080     SourceRange ERange;
21081     Expr *SimpleRefExpr = RefExpr;
21082     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
21083     if (Res.second)
21084       // It will be analyzed later.
21085       Vars.push_back(RefExpr);
21086     ValueDecl *D = Res.first;
21087     if (!D)
21088       continue;
21089 
21090     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
21091     // A list-item cannot appear in more than one nontemporal clause.
21092     if (const Expr *PrevRef =
21093             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
21094       Diag(ELoc, diag::err_omp_used_in_clause_twice)
21095           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
21096       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
21097           << getOpenMPClauseName(OMPC_nontemporal);
21098       continue;
21099     }
21100 
21101     Vars.push_back(RefExpr);
21102   }
21103 
21104   if (Vars.empty())
21105     return nullptr;
21106 
21107   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
21108                                       Vars);
21109 }
21110 
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)21111 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
21112                                             SourceLocation StartLoc,
21113                                             SourceLocation LParenLoc,
21114                                             SourceLocation EndLoc) {
21115   SmallVector<Expr *, 8> Vars;
21116   for (Expr *RefExpr : VarList) {
21117     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
21118     SourceLocation ELoc;
21119     SourceRange ERange;
21120     Expr *SimpleRefExpr = RefExpr;
21121     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21122                               /*AllowArraySection=*/true);
21123     if (Res.second)
21124       // It will be analyzed later.
21125       Vars.push_back(RefExpr);
21126     ValueDecl *D = Res.first;
21127     if (!D)
21128       continue;
21129 
21130     const DSAStackTy::DSAVarData DVar =
21131         DSAStack->getTopDSA(D, /*FromParent=*/true);
21132     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21133     // A list item that appears in the inclusive or exclusive clause must appear
21134     // in a reduction clause with the inscan modifier on the enclosing
21135     // worksharing-loop, worksharing-loop SIMD, or simd construct.
21136     if (DVar.CKind != OMPC_reduction ||
21137         DVar.Modifier != OMPC_REDUCTION_inscan)
21138       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21139           << RefExpr->getSourceRange();
21140 
21141     if (DSAStack->getParentDirective() != OMPD_unknown)
21142       DSAStack->markDeclAsUsedInScanDirective(D);
21143     Vars.push_back(RefExpr);
21144   }
21145 
21146   if (Vars.empty())
21147     return nullptr;
21148 
21149   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21150 }
21151 
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)21152 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
21153                                             SourceLocation StartLoc,
21154                                             SourceLocation LParenLoc,
21155                                             SourceLocation EndLoc) {
21156   SmallVector<Expr *, 8> Vars;
21157   for (Expr *RefExpr : VarList) {
21158     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
21159     SourceLocation ELoc;
21160     SourceRange ERange;
21161     Expr *SimpleRefExpr = RefExpr;
21162     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21163                               /*AllowArraySection=*/true);
21164     if (Res.second)
21165       // It will be analyzed later.
21166       Vars.push_back(RefExpr);
21167     ValueDecl *D = Res.first;
21168     if (!D)
21169       continue;
21170 
21171     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
21172     DSAStackTy::DSAVarData DVar;
21173     if (ParentDirective != OMPD_unknown)
21174       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
21175     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21176     // A list item that appears in the inclusive or exclusive clause must appear
21177     // in a reduction clause with the inscan modifier on the enclosing
21178     // worksharing-loop, worksharing-loop SIMD, or simd construct.
21179     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
21180         DVar.Modifier != OMPC_REDUCTION_inscan) {
21181       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21182           << RefExpr->getSourceRange();
21183     } else {
21184       DSAStack->markDeclAsUsedInScanDirective(D);
21185     }
21186     Vars.push_back(RefExpr);
21187   }
21188 
21189   if (Vars.empty())
21190     return nullptr;
21191 
21192   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21193 }
21194 
21195 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)21196 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
21197   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
21198   if (!OMPAlloctraitT.isNull())
21199     return true;
21200   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
21201   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
21202   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21203     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
21204     return false;
21205   }
21206   Stack->setOMPAlloctraitT(PT.get());
21207   return true;
21208 }
21209 
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)21210 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
21211     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
21212     ArrayRef<UsesAllocatorsData> Data) {
21213   // OpenMP [2.12.5, target Construct]
21214   // allocator is an identifier of omp_allocator_handle_t type.
21215   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
21216     return nullptr;
21217   // OpenMP [2.12.5, target Construct]
21218   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
21219   if (llvm::any_of(
21220           Data,
21221           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
21222       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
21223     return nullptr;
21224   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
21225   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
21226     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
21227     StringRef Allocator =
21228         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
21229     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
21230     PredefinedAllocators.insert(LookupSingleName(
21231         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
21232   }
21233 
21234   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
21235   for (const UsesAllocatorsData &D : Data) {
21236     Expr *AllocatorExpr = nullptr;
21237     // Check allocator expression.
21238     if (D.Allocator->isTypeDependent()) {
21239       AllocatorExpr = D.Allocator;
21240     } else {
21241       // Traits were specified - need to assign new allocator to the specified
21242       // allocator, so it must be an lvalue.
21243       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
21244       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
21245       bool IsPredefinedAllocator = false;
21246       if (DRE)
21247         IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
21248       if (!DRE ||
21249           !(Context.hasSameUnqualifiedType(
21250                 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
21251             Context.typesAreCompatible(AllocatorExpr->getType(),
21252                                        DSAStack->getOMPAllocatorHandleT(),
21253                                        /*CompareUnqualified=*/true)) ||
21254           (!IsPredefinedAllocator &&
21255            (AllocatorExpr->getType().isConstant(Context) ||
21256             !AllocatorExpr->isLValue()))) {
21257         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
21258             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
21259             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
21260         continue;
21261       }
21262       // OpenMP [2.12.5, target Construct]
21263       // Predefined allocators appearing in a uses_allocators clause cannot have
21264       // traits specified.
21265       if (IsPredefinedAllocator && D.AllocatorTraits) {
21266         Diag(D.AllocatorTraits->getExprLoc(),
21267              diag::err_omp_predefined_allocator_with_traits)
21268             << D.AllocatorTraits->getSourceRange();
21269         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
21270             << cast<NamedDecl>(DRE->getDecl())->getName()
21271             << D.Allocator->getSourceRange();
21272         continue;
21273       }
21274       // OpenMP [2.12.5, target Construct]
21275       // Non-predefined allocators appearing in a uses_allocators clause must
21276       // have traits specified.
21277       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
21278         Diag(D.Allocator->getExprLoc(),
21279              diag::err_omp_nonpredefined_allocator_without_traits);
21280         continue;
21281       }
21282       // No allocator traits - just convert it to rvalue.
21283       if (!D.AllocatorTraits)
21284         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
21285       DSAStack->addUsesAllocatorsDecl(
21286           DRE->getDecl(),
21287           IsPredefinedAllocator
21288               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
21289               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
21290     }
21291     Expr *AllocatorTraitsExpr = nullptr;
21292     if (D.AllocatorTraits) {
21293       if (D.AllocatorTraits->isTypeDependent()) {
21294         AllocatorTraitsExpr = D.AllocatorTraits;
21295       } else {
21296         // OpenMP [2.12.5, target Construct]
21297         // Arrays that contain allocator traits that appear in a uses_allocators
21298         // clause must be constant arrays, have constant values and be defined
21299         // in the same scope as the construct in which the clause appears.
21300         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
21301         // Check that traits expr is a constant array.
21302         QualType TraitTy;
21303         if (const ArrayType *Ty =
21304                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
21305           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
21306             TraitTy = ConstArrayTy->getElementType();
21307         if (TraitTy.isNull() ||
21308             !(Context.hasSameUnqualifiedType(TraitTy,
21309                                              DSAStack->getOMPAlloctraitT()) ||
21310               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
21311                                          /*CompareUnqualified=*/true))) {
21312           Diag(D.AllocatorTraits->getExprLoc(),
21313                diag::err_omp_expected_array_alloctraits)
21314               << AllocatorTraitsExpr->getType();
21315           continue;
21316         }
21317         // Do not map by default allocator traits if it is a standalone
21318         // variable.
21319         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
21320           DSAStack->addUsesAllocatorsDecl(
21321               DRE->getDecl(),
21322               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
21323       }
21324     }
21325     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
21326     NewD.Allocator = AllocatorExpr;
21327     NewD.AllocatorTraits = AllocatorTraitsExpr;
21328     NewD.LParenLoc = D.LParenLoc;
21329     NewD.RParenLoc = D.RParenLoc;
21330   }
21331   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
21332                                          NewData);
21333 }
21334 
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)21335 OMPClause *Sema::ActOnOpenMPAffinityClause(
21336     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
21337     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
21338   SmallVector<Expr *, 8> Vars;
21339   for (Expr *RefExpr : Locators) {
21340     assert(RefExpr && "NULL expr in OpenMP shared clause.");
21341     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
21342       // It will be analyzed later.
21343       Vars.push_back(RefExpr);
21344       continue;
21345     }
21346 
21347     SourceLocation ELoc = RefExpr->getExprLoc();
21348     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
21349 
21350     if (!SimpleExpr->isLValue()) {
21351       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21352           << 1 << 0 << RefExpr->getSourceRange();
21353       continue;
21354     }
21355 
21356     ExprResult Res;
21357     {
21358       Sema::TentativeAnalysisScope Trap(*this);
21359       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
21360     }
21361     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21362         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21363       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21364           << 1 << 0 << RefExpr->getSourceRange();
21365       continue;
21366     }
21367     Vars.push_back(SimpleExpr);
21368   }
21369 
21370   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
21371                                    EndLoc, Modifier, Vars);
21372 }
21373