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/EnterExpressionEvaluationContext.h"
31 #include "clang/Sema/Initialization.h"
32 #include "clang/Sema/Lookup.h"
33 #include "clang/Sema/ParsedAttr.h"
34 #include "clang/Sema/Scope.h"
35 #include "clang/Sema/ScopeInfo.h"
36 #include "clang/Sema/SemaInternal.h"
37 #include "llvm/ADT/IndexedMap.h"
38 #include "llvm/ADT/PointerEmbeddedInt.h"
39 #include "llvm/ADT/STLExtras.h"
40 #include "llvm/ADT/SmallSet.h"
41 #include "llvm/ADT/StringExtras.h"
42 #include "llvm/Frontend/OpenMP/OMPAssume.h"
43 #include "llvm/Frontend/OpenMP/OMPConstants.h"
44 #include <optional>
45 #include <set>
46 
47 using namespace clang;
48 using namespace llvm::omp;
49 
50 //===----------------------------------------------------------------------===//
51 // Stack of data-sharing attributes for variables
52 //===----------------------------------------------------------------------===//
53 
54 static const Expr *checkMapClauseExpressionBase(
55     Sema &SemaRef, Expr *E,
56     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
57     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
58 
59 namespace {
60 /// Default data sharing attributes, which can be applied to directive.
61 enum DefaultDataSharingAttributes {
62   DSA_unspecified = 0,       /// Data sharing attribute not specified.
63   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
64   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
65   DSA_private = 1 << 2,      /// Default data sharing attribute 'private'.
66   DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
67 };
68 
69 /// Stack for tracking declarations used in OpenMP directives and
70 /// clauses and their data-sharing attributes.
71 class DSAStackTy {
72 public:
73   struct DSAVarData {
74     OpenMPDirectiveKind DKind = OMPD_unknown;
75     OpenMPClauseKind CKind = OMPC_unknown;
76     unsigned Modifier = 0;
77     const Expr *RefExpr = nullptr;
78     DeclRefExpr *PrivateCopy = nullptr;
79     SourceLocation ImplicitDSALoc;
80     bool AppliedToPointee = false;
81     DSAVarData() = default;
DSAVarData__anon61cef30c0111::DSAStackTy::DSAVarData82     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
83                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
84                SourceLocation ImplicitDSALoc, unsigned Modifier,
85                bool AppliedToPointee)
86         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
87           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
88           AppliedToPointee(AppliedToPointee) {}
89   };
90   using OperatorOffsetTy =
91       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
92   using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
93   /// Kind of the declaration used in the uses_allocators clauses.
94   enum class UsesAllocatorsDeclKind {
95     /// Predefined allocator
96     PredefinedAllocator,
97     /// User-defined allocator
98     UserDefinedAllocator,
99     /// The declaration that represent allocator trait
100     AllocatorTrait,
101   };
102 
103 private:
104   struct DSAInfo {
105     OpenMPClauseKind Attributes = OMPC_unknown;
106     unsigned Modifier = 0;
107     /// Pointer to a reference expression and a flag which shows that the
108     /// variable is marked as lastprivate(true) or not (false).
109     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
110     DeclRefExpr *PrivateCopy = nullptr;
111     /// true if the attribute is applied to the pointee, not the variable
112     /// itself.
113     bool AppliedToPointee = false;
114   };
115   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
116   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
117   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
118   using LoopControlVariablesMapTy =
119       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
120   /// Struct that associates a component with the clause kind where they are
121   /// found.
122   struct MappedExprComponentTy {
123     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
124     OpenMPClauseKind Kind = OMPC_unknown;
125   };
126   using MappedExprComponentsTy =
127       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
128   using CriticalsWithHintsTy =
129       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
130   struct ReductionData {
131     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
132     SourceRange ReductionRange;
133     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
134     ReductionData() = default;
set__anon61cef30c0111::DSAStackTy::ReductionData135     void set(BinaryOperatorKind BO, SourceRange RR) {
136       ReductionRange = RR;
137       ReductionOp = BO;
138     }
set__anon61cef30c0111::DSAStackTy::ReductionData139     void set(const Expr *RefExpr, SourceRange RR) {
140       ReductionRange = RR;
141       ReductionOp = RefExpr;
142     }
143   };
144   using DeclReductionMapTy =
145       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
146   struct DefaultmapInfo {
147     OpenMPDefaultmapClauseModifier ImplicitBehavior =
148         OMPC_DEFAULTMAP_MODIFIER_unknown;
149     SourceLocation SLoc;
150     DefaultmapInfo() = default;
DefaultmapInfo__anon61cef30c0111::DSAStackTy::DefaultmapInfo151     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
152         : ImplicitBehavior(M), SLoc(Loc) {}
153   };
154 
155   struct SharingMapTy {
156     DeclSAMapTy SharingMap;
157     DeclReductionMapTy ReductionMap;
158     UsedRefMapTy AlignedMap;
159     UsedRefMapTy NontemporalMap;
160     MappedExprComponentsTy MappedExprComponents;
161     LoopControlVariablesMapTy LCVMap;
162     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
163     SourceLocation DefaultAttrLoc;
164     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1];
165     OpenMPDirectiveKind Directive = OMPD_unknown;
166     /// GenericLoopDirective with bind clause is mapped to other directives,
167     /// like for, distribute and simd. Presently, set MappedDirective to
168     /// OMPLoop. This may also be used in a similar way for other constructs.
169     OpenMPDirectiveKind MappedDirective = OMPD_unknown;
170     DeclarationNameInfo DirectiveName;
171     Scope *CurScope = nullptr;
172     DeclContext *Context = nullptr;
173     SourceLocation ConstructLoc;
174     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
175     /// get the data (loop counters etc.) about enclosing loop-based construct.
176     /// This data is required during codegen.
177     DoacrossClauseMapTy DoacrossDepends;
178     /// First argument (Expr *) contains optional argument of the
179     /// 'ordered' clause, the second one is true if the regions has 'ordered'
180     /// clause, false otherwise.
181     std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
182     bool RegionHasOrderConcurrent = false;
183     unsigned AssociatedLoops = 1;
184     bool HasMutipleLoops = false;
185     const Decl *PossiblyLoopCounter = nullptr;
186     bool NowaitRegion = false;
187     bool UntiedRegion = false;
188     bool CancelRegion = false;
189     bool LoopStart = false;
190     bool BodyComplete = false;
191     SourceLocation PrevScanLocation;
192     SourceLocation PrevOrderedLocation;
193     SourceLocation InnerTeamsRegionLoc;
194     /// Reference to the taskgroup task_reduction reference expression.
195     Expr *TaskgroupReductionRef = nullptr;
196     llvm::DenseSet<QualType> MappedClassesQualTypes;
197     SmallVector<Expr *, 4> InnerUsedAllocators;
198     llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
199     /// List of globals marked as declare target link in this target region
200     /// (isOpenMPTargetExecutionDirective(Directive) == true).
201     llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
202     /// List of decls used in inclusive/exclusive clauses of the scan directive.
203     llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
204     llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
205         UsesAllocatorsDecls;
206     /// Data is required on creating capture fields for implicit
207     /// default first|private clause.
208     struct ImplicitDefaultFDInfoTy {
209       /// Field decl.
210       const FieldDecl *FD = nullptr;
211       /// Nesting stack level
212       size_t StackLevel = 0;
213       /// Capture variable decl.
214       VarDecl *VD = nullptr;
ImplicitDefaultFDInfoTy__anon61cef30c0111::DSAStackTy::SharingMapTy::ImplicitDefaultFDInfoTy215       ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
216                               VarDecl *VD)
217           : FD(FD), StackLevel(StackLevel), VD(VD) {}
218     };
219     /// List of captured fields
220     llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
221         ImplicitDefaultFirstprivateFDs;
222     Expr *DeclareMapperVar = nullptr;
223     SmallVector<VarDecl *, 16> IteratorVarDecls;
SharingMapTy__anon61cef30c0111::DSAStackTy::SharingMapTy224     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
225                  Scope *CurScope, SourceLocation Loc)
226         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
227           ConstructLoc(Loc) {}
228     SharingMapTy() = default;
229   };
230 
231   using StackTy = SmallVector<SharingMapTy, 4>;
232 
233   /// Stack of used declaration and their data-sharing attributes.
234   DeclSAMapTy Threadprivates;
235   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
236   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
237   /// true, if check for DSA must be from parent directive, false, if
238   /// from current directive.
239   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
240   Sema &SemaRef;
241   bool ForceCapturing = false;
242   /// true if all the variables in the target executable directives must be
243   /// captured by reference.
244   bool ForceCaptureByReferenceInTargetExecutable = false;
245   CriticalsWithHintsTy Criticals;
246   unsigned IgnoredStackElements = 0;
247 
248   /// Iterators over the stack iterate in order from innermost to outermost
249   /// directive.
250   using const_iterator = StackTy::const_reverse_iterator;
begin() const251   const_iterator begin() const {
252     return Stack.empty() ? const_iterator()
253                          : Stack.back().first.rbegin() + IgnoredStackElements;
254   }
end() const255   const_iterator end() const {
256     return Stack.empty() ? const_iterator() : Stack.back().first.rend();
257   }
258   using iterator = StackTy::reverse_iterator;
begin()259   iterator begin() {
260     return Stack.empty() ? iterator()
261                          : Stack.back().first.rbegin() + IgnoredStackElements;
262   }
end()263   iterator end() {
264     return Stack.empty() ? iterator() : Stack.back().first.rend();
265   }
266 
267   // Convenience operations to get at the elements of the stack.
268 
isStackEmpty() const269   bool isStackEmpty() const {
270     return Stack.empty() ||
271            Stack.back().second != CurrentNonCapturingFunctionScope ||
272            Stack.back().first.size() <= IgnoredStackElements;
273   }
getStackSize() const274   size_t getStackSize() const {
275     return isStackEmpty() ? 0
276                           : Stack.back().first.size() - IgnoredStackElements;
277   }
278 
getTopOfStackOrNull()279   SharingMapTy *getTopOfStackOrNull() {
280     size_t Size = getStackSize();
281     if (Size == 0)
282       return nullptr;
283     return &Stack.back().first[Size - 1];
284   }
getTopOfStackOrNull() const285   const SharingMapTy *getTopOfStackOrNull() const {
286     return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
287   }
getTopOfStack()288   SharingMapTy &getTopOfStack() {
289     assert(!isStackEmpty() && "no current directive");
290     return *getTopOfStackOrNull();
291   }
getTopOfStack() const292   const SharingMapTy &getTopOfStack() const {
293     return const_cast<DSAStackTy &>(*this).getTopOfStack();
294   }
295 
getSecondOnStackOrNull()296   SharingMapTy *getSecondOnStackOrNull() {
297     size_t Size = getStackSize();
298     if (Size <= 1)
299       return nullptr;
300     return &Stack.back().first[Size - 2];
301   }
getSecondOnStackOrNull() const302   const SharingMapTy *getSecondOnStackOrNull() const {
303     return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
304   }
305 
306   /// Get the stack element at a certain level (previously returned by
307   /// \c getNestingLevel).
308   ///
309   /// Note that nesting levels count from outermost to innermost, and this is
310   /// the reverse of our iteration order where new inner levels are pushed at
311   /// the front of the stack.
getStackElemAtLevel(unsigned Level)312   SharingMapTy &getStackElemAtLevel(unsigned Level) {
313     assert(Level < getStackSize() && "no such stack element");
314     return Stack.back().first[Level];
315   }
getStackElemAtLevel(unsigned Level) const316   const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
317     return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
318   }
319 
320   DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
321 
322   /// Checks if the variable is a local for OpenMP region.
323   bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
324 
325   /// Vector of previously declared requires directives
326   SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
327   /// omp_allocator_handle_t type.
328   QualType OMPAllocatorHandleT;
329   /// omp_depend_t type.
330   QualType OMPDependT;
331   /// omp_event_handle_t type.
332   QualType OMPEventHandleT;
333   /// omp_alloctrait_t type.
334   QualType OMPAlloctraitT;
335   /// Expression for the predefined allocators.
336   Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
337       nullptr};
338   /// Vector of previously encountered target directives
339   SmallVector<SourceLocation, 2> TargetLocations;
340   SourceLocation AtomicLocation;
341   /// Vector of declare variant construct traits.
342   SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
343 
344 public:
DSAStackTy(Sema & S)345   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
346 
347   /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)348   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
349   /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const350   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
351   /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)352   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
353   /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const354   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
355   /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)356   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
357                     Expr *Allocator) {
358     OMPPredefinedAllocators[AllocatorKind] = Allocator;
359   }
360   /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const361   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
362     return OMPPredefinedAllocators[AllocatorKind];
363   }
364   /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)365   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
366   /// Gets omp_depend_t type.
getOMPDependT() const367   QualType getOMPDependT() const { return OMPDependT; }
368 
369   /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)370   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
371   /// Gets omp_event_handle_t type.
getOMPEventHandleT() const372   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
373 
isClauseParsingMode() const374   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const375   OpenMPClauseKind getClauseParsingMode() const {
376     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
377     return ClauseKindMode;
378   }
setClauseParsingMode(OpenMPClauseKind K)379   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
380 
isBodyComplete() const381   bool isBodyComplete() const {
382     const SharingMapTy *Top = getTopOfStackOrNull();
383     return Top && Top->BodyComplete;
384   }
setBodyComplete()385   void setBodyComplete() { getTopOfStack().BodyComplete = true; }
386 
isForceVarCapturing() const387   bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)388   void setForceVarCapturing(bool V) { ForceCapturing = V; }
389 
setForceCaptureByReferenceInTargetExecutable(bool V)390   void setForceCaptureByReferenceInTargetExecutable(bool V) {
391     ForceCaptureByReferenceInTargetExecutable = V;
392   }
isForceCaptureByReferenceInTargetExecutable() const393   bool isForceCaptureByReferenceInTargetExecutable() const {
394     return ForceCaptureByReferenceInTargetExecutable;
395   }
396 
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)397   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
398             Scope *CurScope, SourceLocation Loc) {
399     assert(!IgnoredStackElements &&
400            "cannot change stack while ignoring elements");
401     if (Stack.empty() ||
402         Stack.back().second != CurrentNonCapturingFunctionScope)
403       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
405     Stack.back().first.back().DefaultAttrLoc = Loc;
406   }
407 
pop()408   void pop() {
409     assert(!IgnoredStackElements &&
410            "cannot change stack while ignoring elements");
411     assert(!Stack.back().first.empty() &&
412            "Data-sharing attributes stack is empty!");
413     Stack.back().first.pop_back();
414   }
415 
416   /// RAII object to temporarily leave the scope of a directive when we want to
417   /// logically operate in its parent.
418   class ParentDirectiveScope {
419     DSAStackTy &Self;
420     bool Active;
421 
422   public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)423     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
424         : Self(Self), Active(false) {
425       if (Activate)
426         enable();
427     }
~ParentDirectiveScope()428     ~ParentDirectiveScope() { disable(); }
disable()429     void disable() {
430       if (Active) {
431         --Self.IgnoredStackElements;
432         Active = false;
433       }
434     }
enable()435     void enable() {
436       if (!Active) {
437         ++Self.IgnoredStackElements;
438         Active = true;
439       }
440     }
441   };
442 
443   /// Marks that we're started loop parsing.
loopInit()444   void loopInit() {
445     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
446            "Expected loop-based directive.");
447     getTopOfStack().LoopStart = true;
448   }
449   /// Start capturing of the variables in the loop context.
loopStart()450   void loopStart() {
451     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
452            "Expected loop-based directive.");
453     getTopOfStack().LoopStart = false;
454   }
455   /// true, if variables are captured, false otherwise.
isLoopStarted() const456   bool isLoopStarted() const {
457     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
458            "Expected loop-based directive.");
459     return !getTopOfStack().LoopStart;
460   }
461   /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)462   void resetPossibleLoopCounter(const Decl *D = nullptr) {
463     getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
464   }
465   /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const466   const Decl *getPossiblyLoopCunter() const {
467     return getTopOfStack().PossiblyLoopCounter;
468   }
469   /// Start new OpenMP region stack in new non-capturing function.
pushFunction()470   void pushFunction() {
471     assert(!IgnoredStackElements &&
472            "cannot change stack while ignoring elements");
473     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
474     assert(!isa<CapturingScopeInfo>(CurFnScope));
475     CurrentNonCapturingFunctionScope = CurFnScope;
476   }
477   /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)478   void popFunction(const FunctionScopeInfo *OldFSI) {
479     assert(!IgnoredStackElements &&
480            "cannot change stack while ignoring elements");
481     if (!Stack.empty() && Stack.back().second == OldFSI) {
482       assert(Stack.back().first.empty());
483       Stack.pop_back();
484     }
485     CurrentNonCapturingFunctionScope = nullptr;
486     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
487       if (!isa<CapturingScopeInfo>(FSI)) {
488         CurrentNonCapturingFunctionScope = FSI;
489         break;
490       }
491     }
492   }
493 
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)494   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
495     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
496   }
497   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const498   getCriticalWithHint(const DeclarationNameInfo &Name) const {
499     auto I = Criticals.find(Name.getAsString());
500     if (I != Criticals.end())
501       return I->second;
502     return std::make_pair(nullptr, llvm::APSInt());
503   }
504   /// If 'aligned' declaration for given variable \a D was not seen yet,
505   /// add it and return NULL; otherwise return previous occurrence's expression
506   /// for diagnostics.
507   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
508   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
509   /// add it and return NULL; otherwise return previous occurrence's expression
510   /// for diagnostics.
511   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
512 
513   /// Register specified variable as loop control variable.
514   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
515   /// Check if the specified variable is a loop control variable for
516   /// current region.
517   /// \return The index of the loop control variable in the list of associated
518   /// for-loops (from outer to inner).
519   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
520   /// Check if the specified variable is a loop control variable for
521   /// parent region.
522   /// \return The index of the loop control variable in the list of associated
523   /// for-loops (from outer to inner).
524   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
525   /// Check if the specified variable is a loop control variable for
526   /// current region.
527   /// \return The index of the loop control variable in the list of associated
528   /// for-loops (from outer to inner).
529   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
530                                          unsigned Level) const;
531   /// Get the loop control variable for the I-th loop (or nullptr) in
532   /// parent directive.
533   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
534 
535   /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)536   void markDeclAsUsedInScanDirective(ValueDecl *D) {
537     if (SharingMapTy *Stack = getSecondOnStackOrNull())
538       Stack->UsedInScanDirective.insert(D);
539   }
540 
541   /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const542   bool isUsedInScanDirective(ValueDecl *D) const {
543     if (const SharingMapTy *Stack = getTopOfStackOrNull())
544       return Stack->UsedInScanDirective.contains(D);
545     return false;
546   }
547 
548   /// Adds explicit data sharing attribute to the specified declaration.
549   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
550               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
551               bool AppliedToPointee = false);
552 
553   /// Adds additional information for the reduction items with the reduction id
554   /// represented as an operator.
555   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
556                                  BinaryOperatorKind BOK);
557   /// Adds additional information for the reduction items with the reduction id
558   /// represented as reduction identifier.
559   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
560                                  const Expr *ReductionRef);
561   /// Returns the location and reduction operation from the innermost parent
562   /// region for the given \p D.
563   const DSAVarData
564   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
565                                    BinaryOperatorKind &BOK,
566                                    Expr *&TaskgroupDescriptor) const;
567   /// Returns the location and reduction operation from the innermost parent
568   /// region for the given \p D.
569   const DSAVarData
570   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
571                                    const Expr *&ReductionRef,
572                                    Expr *&TaskgroupDescriptor) const;
573   /// Return reduction reference expression for the current taskgroup or
574   /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const575   Expr *getTaskgroupReductionRef() const {
576     assert((getTopOfStack().Directive == OMPD_taskgroup ||
577             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
578               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
579              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
580            "taskgroup reference expression requested for non taskgroup or "
581            "parallel/worksharing directive.");
582     return getTopOfStack().TaskgroupReductionRef;
583   }
584   /// Checks if the given \p VD declaration is actually a taskgroup reduction
585   /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const586   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
587     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
589                    ->getDecl() == VD;
590   }
591 
592   /// Returns data sharing attributes from top of the stack for the
593   /// specified declaration.
594   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
595   /// Returns data-sharing attributes for the specified declaration.
596   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
597   /// Returns data-sharing attributes for the specified declaration.
598   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
599   /// Checks if the specified variables has data-sharing attributes which
600   /// match specified \a CPred predicate in any directive which matches \a DPred
601   /// predicate.
602   const DSAVarData
603   hasDSA(ValueDecl *D,
604          const llvm::function_ref<bool(OpenMPClauseKind, bool,
605                                        DefaultDataSharingAttributes)>
606              CPred,
607          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
608          bool FromParent) const;
609   /// Checks if the specified variables has data-sharing attributes which
610   /// match specified \a CPred predicate in any innermost directive which
611   /// matches \a DPred predicate.
612   const DSAVarData
613   hasInnermostDSA(ValueDecl *D,
614                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
615                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
616                   bool FromParent) const;
617   /// Checks if the specified variables has explicit data-sharing
618   /// attributes which match specified \a CPred predicate at the specified
619   /// OpenMP region.
620   bool
621   hasExplicitDSA(const ValueDecl *D,
622                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
623                  unsigned Level, bool NotLastprivate = false) const;
624 
625   /// Returns true if the directive at level \Level matches in the
626   /// specified \a DPred predicate.
627   bool hasExplicitDirective(
628       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
629       unsigned Level) const;
630 
631   /// Finds a directive which matches specified \a DPred predicate.
632   bool hasDirective(
633       const llvm::function_ref<bool(
634           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
635           DPred,
636       bool FromParent) const;
637 
638   /// Returns currently analyzed directive.
getCurrentDirective() const639   OpenMPDirectiveKind getCurrentDirective() const {
640     const SharingMapTy *Top = getTopOfStackOrNull();
641     return Top ? Top->Directive : OMPD_unknown;
642   }
getMappedDirective() const643   OpenMPDirectiveKind getMappedDirective() const {
644     const SharingMapTy *Top = getTopOfStackOrNull();
645     return Top ? Top->MappedDirective : OMPD_unknown;
646   }
setCurrentDirective(OpenMPDirectiveKind NewDK)647   void setCurrentDirective(OpenMPDirectiveKind NewDK) {
648     SharingMapTy *Top = getTopOfStackOrNull();
649     assert(Top &&
650            "Before calling setCurrentDirective Top of Stack not to be NULL.");
651     // Store the old into MappedDirective & assign argument NewDK to Directive.
652     Top->Directive = NewDK;
653   }
setMappedDirective(OpenMPDirectiveKind NewDK)654   void setMappedDirective(OpenMPDirectiveKind NewDK) {
655     SharingMapTy *Top = getTopOfStackOrNull();
656     assert(Top &&
657            "Before calling setMappedDirective Top of Stack not to be NULL.");
658     // Store the old into MappedDirective & assign argument NewDK to Directive.
659     Top->MappedDirective = NewDK;
660   }
661   /// Returns directive kind at specified level.
getDirective(unsigned Level) const662   OpenMPDirectiveKind getDirective(unsigned Level) const {
663     assert(!isStackEmpty() && "No directive at specified level.");
664     return getStackElemAtLevel(Level).Directive;
665   }
666   /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const667   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
668                                        unsigned OpenMPCaptureLevel) const {
669     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
670     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
671     return CaptureRegions[OpenMPCaptureLevel];
672   }
673   /// Returns parent directive.
getParentDirective() const674   OpenMPDirectiveKind getParentDirective() const {
675     const SharingMapTy *Parent = getSecondOnStackOrNull();
676     return Parent ? Parent->Directive : OMPD_unknown;
677   }
678 
679   /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)680   void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
681 
682   /// Checks if the defined 'requires' directive has specified type of clause.
hasRequiresDeclWithClause() const683   template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686         return isa<ClauseType>(C);
687       });
688     });
689   }
690 
691   /// Checks for a duplicate clause amongst previously declared requires
692   /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const693   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
694     bool IsDuplicate = false;
695     for (OMPClause *CNew : ClauseList) {
696       for (const OMPRequiresDecl *D : RequiresDecls) {
697         for (const OMPClause *CPrev : D->clauselists()) {
698           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
699             SemaRef.Diag(CNew->getBeginLoc(),
700                          diag::err_omp_requires_clause_redeclaration)
701                 << getOpenMPClauseName(CNew->getClauseKind());
702             SemaRef.Diag(CPrev->getBeginLoc(),
703                          diag::note_omp_requires_previous_clause)
704                 << getOpenMPClauseName(CPrev->getClauseKind());
705             IsDuplicate = true;
706           }
707         }
708       }
709     }
710     return IsDuplicate;
711   }
712 
713   /// Add location of previously encountered target to internal vector
addTargetDirLocation(SourceLocation LocStart)714   void addTargetDirLocation(SourceLocation LocStart) {
715     TargetLocations.push_back(LocStart);
716   }
717 
718   /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)719   void addAtomicDirectiveLoc(SourceLocation Loc) {
720     if (AtomicLocation.isInvalid())
721       AtomicLocation = Loc;
722   }
723 
724   /// Returns the location of the first encountered atomic directive in the
725   /// module.
getAtomicDirectiveLoc() const726   SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
727 
728   // Return previously encountered target region locations.
getEncounteredTargetLocs() const729   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
730     return TargetLocations;
731   }
732 
733   /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)734   void setDefaultDSANone(SourceLocation Loc) {
735     getTopOfStack().DefaultAttr = DSA_none;
736     getTopOfStack().DefaultAttrLoc = Loc;
737   }
738   /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)739   void setDefaultDSAShared(SourceLocation Loc) {
740     getTopOfStack().DefaultAttr = DSA_shared;
741     getTopOfStack().DefaultAttrLoc = Loc;
742   }
743   /// Set default data sharing attribute to private.
setDefaultDSAPrivate(SourceLocation Loc)744   void setDefaultDSAPrivate(SourceLocation Loc) {
745     getTopOfStack().DefaultAttr = DSA_private;
746     getTopOfStack().DefaultAttrLoc = Loc;
747   }
748   /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)749   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
750     getTopOfStack().DefaultAttr = DSA_firstprivate;
751     getTopOfStack().DefaultAttrLoc = Loc;
752   }
753   /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)754   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
755                          OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
756     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
757     DMI.ImplicitBehavior = M;
758     DMI.SLoc = Loc;
759   }
760   /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)761   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
762     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
763       return getTopOfStack()
764                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
765                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
766              getTopOfStack()
767                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
768                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
769              getTopOfStack()
770                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
771                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
772     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
773            OMPC_DEFAULTMAP_MODIFIER_unknown;
774   }
775 
getConstructTraits()776   ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
777     return ConstructTraits;
778   }
handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,bool ScopeEntry)779   void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
780                             bool ScopeEntry) {
781     if (ScopeEntry)
782       ConstructTraits.append(Traits.begin(), Traits.end());
783     else
784       for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
785         llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
786         assert(Top == Trait && "Something left a trait on the stack!");
787         (void)Trait;
788         (void)Top;
789       }
790   }
791 
getDefaultDSA(unsigned Level) const792   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
793     return getStackSize() <= Level ? DSA_unspecified
794                                    : getStackElemAtLevel(Level).DefaultAttr;
795   }
getDefaultDSA() const796   DefaultDataSharingAttributes getDefaultDSA() const {
797     return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
798   }
getDefaultDSALocation() const799   SourceLocation getDefaultDSALocation() const {
800     return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
801   }
802   OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const803   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
804     return isStackEmpty()
805                ? OMPC_DEFAULTMAP_MODIFIER_unknown
806                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
807   }
808   OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const809   getDefaultmapModifierAtLevel(unsigned Level,
810                                OpenMPDefaultmapClauseKind Kind) const {
811     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
812   }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const813   bool isDefaultmapCapturedByRef(unsigned Level,
814                                  OpenMPDefaultmapClauseKind Kind) const {
815     OpenMPDefaultmapClauseModifier M =
816         getDefaultmapModifierAtLevel(Level, Kind);
817     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
818       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
819              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
820              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
821              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
822     }
823     return true;
824   }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)825   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
826                                      OpenMPDefaultmapClauseKind Kind) {
827     switch (Kind) {
828     case OMPC_DEFAULTMAP_scalar:
829     case OMPC_DEFAULTMAP_pointer:
830       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
831              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
832              (M == OMPC_DEFAULTMAP_MODIFIER_default);
833     case OMPC_DEFAULTMAP_aggregate:
834       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
835     default:
836       break;
837     }
838     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
839   }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const840   bool mustBeFirstprivateAtLevel(unsigned Level,
841                                  OpenMPDefaultmapClauseKind Kind) const {
842     OpenMPDefaultmapClauseModifier M =
843         getDefaultmapModifierAtLevel(Level, Kind);
844     return mustBeFirstprivateBase(M, Kind);
845   }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const846   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
847     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
848     return mustBeFirstprivateBase(M, Kind);
849   }
850 
851   /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)852   bool isThreadPrivate(VarDecl *D) {
853     const DSAVarData DVar = getTopDSA(D, false);
854     return isOpenMPThreadPrivate(DVar.CKind);
855   }
856 
857   /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)858   void setOrderedRegion(bool IsOrdered, const Expr *Param,
859                         OMPOrderedClause *Clause) {
860     if (IsOrdered)
861       getTopOfStack().OrderedRegion.emplace(Param, Clause);
862     else
863       getTopOfStack().OrderedRegion.reset();
864   }
865   /// Returns true, if region is ordered (has associated 'ordered' clause),
866   /// false - otherwise.
isOrderedRegion() const867   bool isOrderedRegion() const {
868     if (const SharingMapTy *Top = getTopOfStackOrNull())
869       return Top->OrderedRegion.has_value();
870     return false;
871   }
872   /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const873   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
874     if (const SharingMapTy *Top = getTopOfStackOrNull())
875       if (Top->OrderedRegion)
876         return *Top->OrderedRegion;
877     return std::make_pair(nullptr, nullptr);
878   }
879   /// Returns true, if parent region is ordered (has associated
880   /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const881   bool isParentOrderedRegion() const {
882     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
883       return Parent->OrderedRegion.has_value();
884     return false;
885   }
886   /// Returns optional parameter for the ordered region.
887   std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const888   getParentOrderedRegionParam() const {
889     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
890       if (Parent->OrderedRegion)
891         return *Parent->OrderedRegion;
892     return std::make_pair(nullptr, nullptr);
893   }
894   /// Marks current region as having an 'order' clause.
setRegionHasOrderConcurrent(bool HasOrderConcurrent)895   void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
896     getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
897   }
898   /// Returns true, if parent region is order (has associated
899   /// 'order' clause), false - otherwise.
isParentOrderConcurrent() const900   bool isParentOrderConcurrent() const {
901     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
902       return Parent->RegionHasOrderConcurrent;
903     return false;
904   }
905   /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)906   void setNowaitRegion(bool IsNowait = true) {
907     getTopOfStack().NowaitRegion = IsNowait;
908   }
909   /// Returns true, if parent region is nowait (has associated
910   /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const911   bool isParentNowaitRegion() const {
912     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
913       return Parent->NowaitRegion;
914     return false;
915   }
916   /// Marks current region as untied (it has a 'untied' clause).
setUntiedRegion(bool IsUntied=true)917   void setUntiedRegion(bool IsUntied = true) {
918     getTopOfStack().UntiedRegion = IsUntied;
919   }
920   /// Return true if current region is untied.
isUntiedRegion() const921   bool isUntiedRegion() const {
922     const SharingMapTy *Top = getTopOfStackOrNull();
923     return Top ? Top->UntiedRegion : false;
924   }
925   /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)926   void setParentCancelRegion(bool Cancel = true) {
927     if (SharingMapTy *Parent = getSecondOnStackOrNull())
928       Parent->CancelRegion |= Cancel;
929   }
930   /// Return true if current region has inner cancel construct.
isCancelRegion() const931   bool isCancelRegion() const {
932     const SharingMapTy *Top = getTopOfStackOrNull();
933     return Top ? Top->CancelRegion : false;
934   }
935 
936   /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)937   void setParentHasScanDirective(SourceLocation Loc) {
938     if (SharingMapTy *Parent = getSecondOnStackOrNull())
939       Parent->PrevScanLocation = Loc;
940   }
941   /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const942   bool doesParentHasScanDirective() const {
943     const SharingMapTy *Top = getSecondOnStackOrNull();
944     return Top ? Top->PrevScanLocation.isValid() : false;
945   }
946   /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const947   SourceLocation getParentScanDirectiveLoc() const {
948     const SharingMapTy *Top = getSecondOnStackOrNull();
949     return Top ? Top->PrevScanLocation : SourceLocation();
950   }
951   /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)952   void setParentHasOrderedDirective(SourceLocation Loc) {
953     if (SharingMapTy *Parent = getSecondOnStackOrNull())
954       Parent->PrevOrderedLocation = Loc;
955   }
956   /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const957   bool doesParentHasOrderedDirective() const {
958     const SharingMapTy *Top = getSecondOnStackOrNull();
959     return Top ? Top->PrevOrderedLocation.isValid() : false;
960   }
961   /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const962   SourceLocation getParentOrderedDirectiveLoc() const {
963     const SharingMapTy *Top = getSecondOnStackOrNull();
964     return Top ? Top->PrevOrderedLocation : SourceLocation();
965   }
966 
967   /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)968   void setAssociatedLoops(unsigned Val) {
969     getTopOfStack().AssociatedLoops = Val;
970     if (Val > 1)
971       getTopOfStack().HasMutipleLoops = true;
972   }
973   /// Return collapse value for region.
getAssociatedLoops() const974   unsigned getAssociatedLoops() const {
975     const SharingMapTy *Top = getTopOfStackOrNull();
976     return Top ? Top->AssociatedLoops : 0;
977   }
978   /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const979   bool hasMutipleLoops() const {
980     const SharingMapTy *Top = getTopOfStackOrNull();
981     return Top ? Top->HasMutipleLoops : false;
982   }
983 
984   /// Marks current target region as one with closely nested teams
985   /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)986   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
987     if (SharingMapTy *Parent = getSecondOnStackOrNull())
988       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
989   }
990   /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const991   bool hasInnerTeamsRegion() const {
992     return getInnerTeamsRegionLoc().isValid();
993   }
994   /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const995   SourceLocation getInnerTeamsRegionLoc() const {
996     const SharingMapTy *Top = getTopOfStackOrNull();
997     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
998   }
999 
getCurScope() const1000   Scope *getCurScope() const {
1001     const SharingMapTy *Top = getTopOfStackOrNull();
1002     return Top ? Top->CurScope : nullptr;
1003   }
setContext(DeclContext * DC)1004   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const1005   SourceLocation getConstructLoc() const {
1006     const SharingMapTy *Top = getTopOfStackOrNull();
1007     return Top ? Top->ConstructLoc : SourceLocation();
1008   }
1009 
1010   /// Do the check specified in \a Check to all component lists and return true
1011   /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const1012   bool checkMappableExprComponentListsForDecl(
1013       const ValueDecl *VD, bool CurrentRegionOnly,
1014       const llvm::function_ref<
1015           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1016                OpenMPClauseKind)>
1017           Check) const {
1018     if (isStackEmpty())
1019       return false;
1020     auto SI = begin();
1021     auto SE = end();
1022 
1023     if (SI == SE)
1024       return false;
1025 
1026     if (CurrentRegionOnly)
1027       SE = std::next(SI);
1028     else
1029       std::advance(SI, 1);
1030 
1031     for (; SI != SE; ++SI) {
1032       auto MI = SI->MappedExprComponents.find(VD);
1033       if (MI != SI->MappedExprComponents.end())
1034         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1035              MI->second.Components)
1036           if (Check(L, MI->second.Kind))
1037             return true;
1038     }
1039     return false;
1040   }
1041 
1042   /// Do the check specified in \a Check to all component lists at a given level
1043   /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const1044   bool checkMappableExprComponentListsForDeclAtLevel(
1045       const ValueDecl *VD, unsigned Level,
1046       const llvm::function_ref<
1047           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1048                OpenMPClauseKind)>
1049           Check) const {
1050     if (getStackSize() <= Level)
1051       return false;
1052 
1053     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1054     auto MI = StackElem.MappedExprComponents.find(VD);
1055     if (MI != StackElem.MappedExprComponents.end())
1056       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1057            MI->second.Components)
1058         if (Check(L, MI->second.Kind))
1059           return true;
1060     return false;
1061   }
1062 
1063   /// Create a new mappable expression component list associated with a given
1064   /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)1065   void addMappableExpressionComponents(
1066       const ValueDecl *VD,
1067       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1068       OpenMPClauseKind WhereFoundClauseKind) {
1069     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1070     // Create new entry and append the new components there.
1071     MEC.Components.resize(MEC.Components.size() + 1);
1072     MEC.Components.back().append(Components.begin(), Components.end());
1073     MEC.Kind = WhereFoundClauseKind;
1074   }
1075 
getNestingLevel() const1076   unsigned getNestingLevel() const {
1077     assert(!isStackEmpty());
1078     return getStackSize() - 1;
1079   }
addDoacrossDependClause(OMPClause * C,const OperatorOffsetTy & OpsOffs)1080   void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) {
1081     SharingMapTy *Parent = getSecondOnStackOrNull();
1082     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1083     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1084   }
1085   llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
getDoacrossDependClauses() const1086   getDoacrossDependClauses() const {
1087     const SharingMapTy &StackElem = getTopOfStack();
1088     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1089       const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1090       return llvm::make_range(Ref.begin(), Ref.end());
1091     }
1092     return llvm::make_range(StackElem.DoacrossDepends.end(),
1093                             StackElem.DoacrossDepends.end());
1094   }
1095 
1096   // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1097   void addMappedClassesQualTypes(QualType QT) {
1098     SharingMapTy &StackElem = getTopOfStack();
1099     StackElem.MappedClassesQualTypes.insert(QT);
1100   }
1101 
1102   // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1103   bool isClassPreviouslyMapped(QualType QT) const {
1104     const SharingMapTy &StackElem = getTopOfStack();
1105     return StackElem.MappedClassesQualTypes.contains(QT);
1106   }
1107 
1108   /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1109   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1110     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1111                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1112            "Expected declare target link global.");
1113     for (auto &Elem : *this) {
1114       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1115         Elem.DeclareTargetLinkVarDecls.push_back(E);
1116         return;
1117       }
1118     }
1119   }
1120 
1121   /// Returns the list of globals with declare target link if current directive
1122   /// is target.
getLinkGlobals() const1123   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1124     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1125            "Expected target executable directive.");
1126     return getTopOfStack().DeclareTargetLinkVarDecls;
1127   }
1128 
1129   /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1130   void addInnerAllocatorExpr(Expr *E) {
1131     getTopOfStack().InnerUsedAllocators.push_back(E);
1132   }
1133   /// Return list of used allocators.
getInnerAllocators() const1134   ArrayRef<Expr *> getInnerAllocators() const {
1135     return getTopOfStack().InnerUsedAllocators;
1136   }
1137   /// Marks the declaration as implicitly firstprivate nin the task-based
1138   /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1139   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1140     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1141   }
1142   /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1143   bool isImplicitTaskFirstprivate(Decl *D) const {
1144     return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1145   }
1146 
1147   /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1148   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1149     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1150   }
1151   /// Checks if specified decl is used in uses allocator clause as the
1152   /// allocator.
1153   std::optional<UsesAllocatorsDeclKind>
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1154   isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1155     const SharingMapTy &StackElem = getTopOfStack();
1156     auto I = StackElem.UsesAllocatorsDecls.find(D);
1157     if (I == StackElem.UsesAllocatorsDecls.end())
1158       return std::nullopt;
1159     return I->getSecond();
1160   }
1161   std::optional<UsesAllocatorsDeclKind>
isUsesAllocatorsDecl(const Decl * D) const1162   isUsesAllocatorsDecl(const Decl *D) const {
1163     const SharingMapTy &StackElem = getTopOfStack();
1164     auto I = StackElem.UsesAllocatorsDecls.find(D);
1165     if (I == StackElem.UsesAllocatorsDecls.end())
1166       return std::nullopt;
1167     return I->getSecond();
1168   }
1169 
addDeclareMapperVarRef(Expr * Ref)1170   void addDeclareMapperVarRef(Expr *Ref) {
1171     SharingMapTy &StackElem = getTopOfStack();
1172     StackElem.DeclareMapperVar = Ref;
1173   }
getDeclareMapperVarRef() const1174   const Expr *getDeclareMapperVarRef() const {
1175     const SharingMapTy *Top = getTopOfStackOrNull();
1176     return Top ? Top->DeclareMapperVar : nullptr;
1177   }
1178 
1179   /// Add a new iterator variable.
addIteratorVarDecl(VarDecl * VD)1180   void addIteratorVarDecl(VarDecl *VD) {
1181     SharingMapTy &StackElem = getTopOfStack();
1182     StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1183   }
1184   /// Check if variable declaration is an iterator VarDecl.
isIteratorVarDecl(const VarDecl * VD) const1185   bool isIteratorVarDecl(const VarDecl *VD) const {
1186     const SharingMapTy *Top = getTopOfStackOrNull();
1187     if (!Top)
1188       return false;
1189 
1190     return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl());
1191   }
1192   /// get captured field from ImplicitDefaultFirstprivateFDs
getImplicitFDCapExprDecl(const FieldDecl * FD) const1193   VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1194     const_iterator I = begin();
1195     const_iterator EndI = end();
1196     size_t StackLevel = getStackSize();
1197     for (; I != EndI; ++I) {
1198       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1199         break;
1200       StackLevel--;
1201     }
1202     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1203     if (I == EndI)
1204       return nullptr;
1205     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206       if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1207         return IFD.VD;
1208     return nullptr;
1209   }
1210   /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
isImplicitDefaultFirstprivateFD(VarDecl * VD) const1211   bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1212     const_iterator I = begin();
1213     const_iterator EndI = end();
1214     for (; I != EndI; ++I)
1215       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1216         break;
1217     if (I == EndI)
1218       return false;
1219     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1220       if (IFD.VD == VD)
1221         return true;
1222     return false;
1223   }
1224   /// Store capture FD info in ImplicitDefaultFirstprivateFDs
addImplicitDefaultFirstprivateFD(const FieldDecl * FD,VarDecl * VD)1225   void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1226     iterator I = begin();
1227     const_iterator EndI = end();
1228     size_t StackLevel = getStackSize();
1229     for (; I != EndI; ++I) {
1230       if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1231         I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1232         break;
1233       }
1234       StackLevel--;
1235     }
1236     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1237   }
1238 };
1239 
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1240 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1241   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1242 }
1243 
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1244 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1245   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1246          DKind == OMPD_unknown;
1247 }
1248 
1249 } // namespace
1250 
getExprAsWritten(const Expr * E)1251 static const Expr *getExprAsWritten(const Expr *E) {
1252   if (const auto *FE = dyn_cast<FullExpr>(E))
1253     E = FE->getSubExpr();
1254 
1255   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1256     E = MTE->getSubExpr();
1257 
1258   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1259     E = Binder->getSubExpr();
1260 
1261   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1262     E = ICE->getSubExprAsWritten();
1263   return E->IgnoreParens();
1264 }
1265 
getExprAsWritten(Expr * E)1266 static Expr *getExprAsWritten(Expr *E) {
1267   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1268 }
1269 
getCanonicalDecl(const ValueDecl * D)1270 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1271   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1272     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1273       D = ME->getMemberDecl();
1274   const auto *VD = dyn_cast<VarDecl>(D);
1275   const auto *FD = dyn_cast<FieldDecl>(D);
1276   if (VD != nullptr) {
1277     VD = VD->getCanonicalDecl();
1278     D = VD;
1279   } else {
1280     assert(FD);
1281     FD = FD->getCanonicalDecl();
1282     D = FD;
1283   }
1284   return D;
1285 }
1286 
getCanonicalDecl(ValueDecl * D)1287 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1288   return const_cast<ValueDecl *>(
1289       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1290 }
1291 
getDSA(const_iterator & Iter,ValueDecl * D) const1292 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1293                                           ValueDecl *D) const {
1294   D = getCanonicalDecl(D);
1295   auto *VD = dyn_cast<VarDecl>(D);
1296   const auto *FD = dyn_cast<FieldDecl>(D);
1297   DSAVarData DVar;
1298   if (Iter == end()) {
1299     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1300     // in a region but not in construct]
1301     //  File-scope or namespace-scope variables referenced in called routines
1302     //  in the region are shared unless they appear in a threadprivate
1303     //  directive.
1304     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1305       DVar.CKind = OMPC_shared;
1306 
1307     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1308     // in a region but not in construct]
1309     //  Variables with static storage duration that are declared in called
1310     //  routines in the region are shared.
1311     if (VD && VD->hasGlobalStorage())
1312       DVar.CKind = OMPC_shared;
1313 
1314     // Non-static data members are shared by default.
1315     if (FD)
1316       DVar.CKind = OMPC_shared;
1317 
1318     return DVar;
1319   }
1320 
1321   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1322   // in a Construct, C/C++, predetermined, p.1]
1323   // Variables with automatic storage duration that are declared in a scope
1324   // inside the construct are private.
1325   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1326       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1327     DVar.CKind = OMPC_private;
1328     return DVar;
1329   }
1330 
1331   DVar.DKind = Iter->Directive;
1332   // Explicitly specified attributes and local variables with predetermined
1333   // attributes.
1334   if (Iter->SharingMap.count(D)) {
1335     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1336     DVar.RefExpr = Data.RefExpr.getPointer();
1337     DVar.PrivateCopy = Data.PrivateCopy;
1338     DVar.CKind = Data.Attributes;
1339     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1340     DVar.Modifier = Data.Modifier;
1341     DVar.AppliedToPointee = Data.AppliedToPointee;
1342     return DVar;
1343   }
1344 
1345   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1346   // in a Construct, C/C++, implicitly determined, p.1]
1347   //  In a parallel or task construct, the data-sharing attributes of these
1348   //  variables are determined by the default clause, if present.
1349   switch (Iter->DefaultAttr) {
1350   case DSA_shared:
1351     DVar.CKind = OMPC_shared;
1352     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1353     return DVar;
1354   case DSA_none:
1355     return DVar;
1356   case DSA_firstprivate:
1357     if (VD && VD->getStorageDuration() == SD_Static &&
1358         VD->getDeclContext()->isFileContext()) {
1359       DVar.CKind = OMPC_unknown;
1360     } else {
1361       DVar.CKind = OMPC_firstprivate;
1362     }
1363     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1364     return DVar;
1365   case DSA_private:
1366     // each variable with static storage duration that is declared
1367     // in a namespace or global scope and referenced in the construct,
1368     // and that does not have a predetermined data-sharing attribute
1369     if (VD && VD->getStorageDuration() == SD_Static &&
1370         VD->getDeclContext()->isFileContext()) {
1371       DVar.CKind = OMPC_unknown;
1372     } else {
1373       DVar.CKind = OMPC_private;
1374     }
1375     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1376     return DVar;
1377   case DSA_unspecified:
1378     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1379     // in a Construct, implicitly determined, p.2]
1380     //  In a parallel construct, if no default clause is present, these
1381     //  variables are shared.
1382     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1383     if ((isOpenMPParallelDirective(DVar.DKind) &&
1384          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1385         isOpenMPTeamsDirective(DVar.DKind)) {
1386       DVar.CKind = OMPC_shared;
1387       return DVar;
1388     }
1389 
1390     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1391     // in a Construct, implicitly determined, p.4]
1392     //  In a task construct, if no default clause is present, a variable that in
1393     //  the enclosing context is determined to be shared by all implicit tasks
1394     //  bound to the current team is shared.
1395     if (isOpenMPTaskingDirective(DVar.DKind)) {
1396       DSAVarData DVarTemp;
1397       const_iterator I = Iter, E = end();
1398       do {
1399         ++I;
1400         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1401         // Referenced in a Construct, implicitly determined, p.6]
1402         //  In a task construct, if no default clause is present, a variable
1403         //  whose data-sharing attribute is not determined by the rules above is
1404         //  firstprivate.
1405         DVarTemp = getDSA(I, D);
1406         if (DVarTemp.CKind != OMPC_shared) {
1407           DVar.RefExpr = nullptr;
1408           DVar.CKind = OMPC_firstprivate;
1409           return DVar;
1410         }
1411       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1412       DVar.CKind =
1413           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1414       return DVar;
1415     }
1416   }
1417   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1418   // in a Construct, implicitly determined, p.3]
1419   //  For constructs other than task, if no default clause is present, these
1420   //  variables inherit their data-sharing attributes from the enclosing
1421   //  context.
1422   return getDSA(++Iter, D);
1423 }
1424 
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1425 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1426                                          const Expr *NewDE) {
1427   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1428   D = getCanonicalDecl(D);
1429   SharingMapTy &StackElem = getTopOfStack();
1430   auto It = StackElem.AlignedMap.find(D);
1431   if (It == StackElem.AlignedMap.end()) {
1432     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1433     StackElem.AlignedMap[D] = NewDE;
1434     return nullptr;
1435   }
1436   assert(It->second && "Unexpected nullptr expr in the aligned map");
1437   return It->second;
1438 }
1439 
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1440 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1441                                              const Expr *NewDE) {
1442   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1443   D = getCanonicalDecl(D);
1444   SharingMapTy &StackElem = getTopOfStack();
1445   auto It = StackElem.NontemporalMap.find(D);
1446   if (It == StackElem.NontemporalMap.end()) {
1447     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1448     StackElem.NontemporalMap[D] = NewDE;
1449     return nullptr;
1450   }
1451   assert(It->second && "Unexpected nullptr expr in the aligned map");
1452   return It->second;
1453 }
1454 
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1455 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1456   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1457   D = getCanonicalDecl(D);
1458   SharingMapTy &StackElem = getTopOfStack();
1459   StackElem.LCVMap.try_emplace(
1460       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1461 }
1462 
1463 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1464 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1465   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1466   D = getCanonicalDecl(D);
1467   const SharingMapTy &StackElem = getTopOfStack();
1468   auto It = StackElem.LCVMap.find(D);
1469   if (It != StackElem.LCVMap.end())
1470     return It->second;
1471   return {0, nullptr};
1472 }
1473 
1474 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1475 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1476   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1477   D = getCanonicalDecl(D);
1478   for (unsigned I = Level + 1; I > 0; --I) {
1479     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1480     auto It = StackElem.LCVMap.find(D);
1481     if (It != StackElem.LCVMap.end())
1482       return It->second;
1483   }
1484   return {0, nullptr};
1485 }
1486 
1487 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1488 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1489   const SharingMapTy *Parent = getSecondOnStackOrNull();
1490   assert(Parent && "Data-sharing attributes stack is empty");
1491   D = getCanonicalDecl(D);
1492   auto It = Parent->LCVMap.find(D);
1493   if (It != Parent->LCVMap.end())
1494     return It->second;
1495   return {0, nullptr};
1496 }
1497 
getParentLoopControlVariable(unsigned I) const1498 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1499   const SharingMapTy *Parent = getSecondOnStackOrNull();
1500   assert(Parent && "Data-sharing attributes stack is empty");
1501   if (Parent->LCVMap.size() < I)
1502     return nullptr;
1503   for (const auto &Pair : Parent->LCVMap)
1504     if (Pair.second.first == I)
1505       return Pair.first;
1506   return nullptr;
1507 }
1508 
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1509 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1510                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1511                         bool AppliedToPointee) {
1512   D = getCanonicalDecl(D);
1513   if (A == OMPC_threadprivate) {
1514     DSAInfo &Data = Threadprivates[D];
1515     Data.Attributes = A;
1516     Data.RefExpr.setPointer(E);
1517     Data.PrivateCopy = nullptr;
1518     Data.Modifier = Modifier;
1519   } else {
1520     DSAInfo &Data = getTopOfStack().SharingMap[D];
1521     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1522            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1523            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1524            (isLoopControlVariable(D).first && A == OMPC_private));
1525     Data.Modifier = Modifier;
1526     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1527       Data.RefExpr.setInt(/*IntVal=*/true);
1528       return;
1529     }
1530     const bool IsLastprivate =
1531         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1532     Data.Attributes = A;
1533     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1534     Data.PrivateCopy = PrivateCopy;
1535     Data.AppliedToPointee = AppliedToPointee;
1536     if (PrivateCopy) {
1537       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1538       Data.Modifier = Modifier;
1539       Data.Attributes = A;
1540       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1541       Data.PrivateCopy = nullptr;
1542       Data.AppliedToPointee = AppliedToPointee;
1543     }
1544   }
1545 }
1546 
1547 /// 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)1548 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1549                              StringRef Name, const AttrVec *Attrs = nullptr,
1550                              DeclRefExpr *OrigRef = nullptr) {
1551   DeclContext *DC = SemaRef.CurContext;
1552   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1553   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1554   auto *Decl =
1555       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1556   if (Attrs) {
1557     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1558          I != E; ++I)
1559       Decl->addAttr(*I);
1560   }
1561   Decl->setImplicit();
1562   if (OrigRef) {
1563     Decl->addAttr(
1564         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1565   }
1566   return Decl;
1567 }
1568 
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1569 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1570                                      SourceLocation Loc,
1571                                      bool RefersToCapture = false) {
1572   D->setReferenced();
1573   D->markUsed(S.Context);
1574   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1575                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1576                              VK_LValue);
1577 }
1578 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1579 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1580                                            BinaryOperatorKind BOK) {
1581   D = getCanonicalDecl(D);
1582   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1583   assert(
1584       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1585       "Additional reduction info may be specified only for reduction items.");
1586   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1587   assert(ReductionData.ReductionRange.isInvalid() &&
1588          (getTopOfStack().Directive == OMPD_taskgroup ||
1589           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1590             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1591            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1592          "Additional reduction info may be specified only once for reduction "
1593          "items.");
1594   ReductionData.set(BOK, SR);
1595   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1596   if (!TaskgroupReductionRef) {
1597     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1598                                SemaRef.Context.VoidPtrTy, ".task_red.");
1599     TaskgroupReductionRef =
1600         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1601   }
1602 }
1603 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1604 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1605                                            const Expr *ReductionRef) {
1606   D = getCanonicalDecl(D);
1607   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1608   assert(
1609       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1610       "Additional reduction info may be specified only for reduction items.");
1611   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1612   assert(ReductionData.ReductionRange.isInvalid() &&
1613          (getTopOfStack().Directive == OMPD_taskgroup ||
1614           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1615             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1616            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1617          "Additional reduction info may be specified only once for reduction "
1618          "items.");
1619   ReductionData.set(ReductionRef, SR);
1620   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1621   if (!TaskgroupReductionRef) {
1622     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1623                                SemaRef.Context.VoidPtrTy, ".task_red.");
1624     TaskgroupReductionRef =
1625         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1626   }
1627 }
1628 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1629 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1630     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1631     Expr *&TaskgroupDescriptor) const {
1632   D = getCanonicalDecl(D);
1633   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1634   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1635     const DSAInfo &Data = I->SharingMap.lookup(D);
1636     if (Data.Attributes != OMPC_reduction ||
1637         Data.Modifier != OMPC_REDUCTION_task)
1638       continue;
1639     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1640     if (!ReductionData.ReductionOp ||
1641         ReductionData.ReductionOp.is<const Expr *>())
1642       return DSAVarData();
1643     SR = ReductionData.ReductionRange;
1644     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1645     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1646                                        "expression for the descriptor is not "
1647                                        "set.");
1648     TaskgroupDescriptor = I->TaskgroupReductionRef;
1649     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1650                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1651                       /*AppliedToPointee=*/false);
1652   }
1653   return DSAVarData();
1654 }
1655 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1656 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1657     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1658     Expr *&TaskgroupDescriptor) const {
1659   D = getCanonicalDecl(D);
1660   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1661   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1662     const DSAInfo &Data = I->SharingMap.lookup(D);
1663     if (Data.Attributes != OMPC_reduction ||
1664         Data.Modifier != OMPC_REDUCTION_task)
1665       continue;
1666     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1667     if (!ReductionData.ReductionOp ||
1668         !ReductionData.ReductionOp.is<const Expr *>())
1669       return DSAVarData();
1670     SR = ReductionData.ReductionRange;
1671     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1672     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1673                                        "expression for the descriptor is not "
1674                                        "set.");
1675     TaskgroupDescriptor = I->TaskgroupReductionRef;
1676     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1677                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1678                       /*AppliedToPointee=*/false);
1679   }
1680   return DSAVarData();
1681 }
1682 
isOpenMPLocal(VarDecl * D,const_iterator I) const1683 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1684   D = D->getCanonicalDecl();
1685   for (const_iterator E = end(); I != E; ++I) {
1686     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1687         isOpenMPTargetExecutionDirective(I->Directive)) {
1688       if (I->CurScope) {
1689         Scope *TopScope = I->CurScope->getParent();
1690         Scope *CurScope = getCurScope();
1691         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1692           CurScope = CurScope->getParent();
1693         return CurScope != TopScope;
1694       }
1695       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1696         if (I->Context == DC)
1697           return true;
1698       return false;
1699     }
1700   }
1701   return false;
1702 }
1703 
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1704 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1705                                   bool AcceptIfMutable = true,
1706                                   bool *IsClassType = nullptr) {
1707   ASTContext &Context = SemaRef.getASTContext();
1708   Type = Type.getNonReferenceType().getCanonicalType();
1709   bool IsConstant = Type.isConstant(Context);
1710   Type = Context.getBaseElementType(Type);
1711   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1712                                 ? Type->getAsCXXRecordDecl()
1713                                 : nullptr;
1714   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1715     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1716       RD = CTD->getTemplatedDecl();
1717   if (IsClassType)
1718     *IsClassType = RD;
1719   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1720                          RD->hasDefinition() && RD->hasMutableFields());
1721 }
1722 
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1723 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1724                                       QualType Type, OpenMPClauseKind CKind,
1725                                       SourceLocation ELoc,
1726                                       bool AcceptIfMutable = true,
1727                                       bool ListItemNotVar = false) {
1728   ASTContext &Context = SemaRef.getASTContext();
1729   bool IsClassType;
1730   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1731     unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1732                     : IsClassType  ? diag::err_omp_const_not_mutable_variable
1733                                    : diag::err_omp_const_variable;
1734     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1735     if (!ListItemNotVar && D) {
1736       const VarDecl *VD = dyn_cast<VarDecl>(D);
1737       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1738                                VarDecl::DeclarationOnly;
1739       SemaRef.Diag(D->getLocation(),
1740                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1741           << D;
1742     }
1743     return true;
1744   }
1745   return false;
1746 }
1747 
getTopDSA(ValueDecl * D,bool FromParent)1748 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1749                                                    bool FromParent) {
1750   D = getCanonicalDecl(D);
1751   DSAVarData DVar;
1752 
1753   auto *VD = dyn_cast<VarDecl>(D);
1754   auto TI = Threadprivates.find(D);
1755   if (TI != Threadprivates.end()) {
1756     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1757     DVar.CKind = OMPC_threadprivate;
1758     DVar.Modifier = TI->getSecond().Modifier;
1759     return DVar;
1760   }
1761   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1762     DVar.RefExpr = buildDeclRefExpr(
1763         SemaRef, VD, D->getType().getNonReferenceType(),
1764         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1765     DVar.CKind = OMPC_threadprivate;
1766     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1767     return DVar;
1768   }
1769   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1770   // in a Construct, C/C++, predetermined, p.1]
1771   //  Variables appearing in threadprivate directives are threadprivate.
1772   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1773        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1774          SemaRef.getLangOpts().OpenMPUseTLS &&
1775          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1776       (VD && VD->getStorageClass() == SC_Register &&
1777        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1778     DVar.RefExpr = buildDeclRefExpr(
1779         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1780     DVar.CKind = OMPC_threadprivate;
1781     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1782     return DVar;
1783   }
1784   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1785       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1786       !isLoopControlVariable(D).first) {
1787     const_iterator IterTarget =
1788         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1789           return isOpenMPTargetExecutionDirective(Data.Directive);
1790         });
1791     if (IterTarget != end()) {
1792       const_iterator ParentIterTarget = IterTarget + 1;
1793       for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1794         if (isOpenMPLocal(VD, Iter)) {
1795           DVar.RefExpr =
1796               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1797                                D->getLocation());
1798           DVar.CKind = OMPC_threadprivate;
1799           return DVar;
1800         }
1801       }
1802       if (!isClauseParsingMode() || IterTarget != begin()) {
1803         auto DSAIter = IterTarget->SharingMap.find(D);
1804         if (DSAIter != IterTarget->SharingMap.end() &&
1805             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1806           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1807           DVar.CKind = OMPC_threadprivate;
1808           return DVar;
1809         }
1810         const_iterator End = end();
1811         if (!SemaRef.isOpenMPCapturedByRef(D,
1812                                            std::distance(ParentIterTarget, End),
1813                                            /*OpenMPCaptureLevel=*/0)) {
1814           DVar.RefExpr =
1815               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1816                                IterTarget->ConstructLoc);
1817           DVar.CKind = OMPC_threadprivate;
1818           return DVar;
1819         }
1820       }
1821     }
1822   }
1823 
1824   if (isStackEmpty())
1825     // Not in OpenMP execution region and top scope was already checked.
1826     return DVar;
1827 
1828   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1829   // in a Construct, C/C++, predetermined, p.4]
1830   //  Static data members are shared.
1831   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1832   // in a Construct, C/C++, predetermined, p.7]
1833   //  Variables with static storage duration that are declared in a scope
1834   //  inside the construct are shared.
1835   if (VD && VD->isStaticDataMember()) {
1836     // Check for explicitly specified attributes.
1837     const_iterator I = begin();
1838     const_iterator EndI = end();
1839     if (FromParent && I != EndI)
1840       ++I;
1841     if (I != EndI) {
1842       auto It = I->SharingMap.find(D);
1843       if (It != I->SharingMap.end()) {
1844         const DSAInfo &Data = It->getSecond();
1845         DVar.RefExpr = Data.RefExpr.getPointer();
1846         DVar.PrivateCopy = Data.PrivateCopy;
1847         DVar.CKind = Data.Attributes;
1848         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849         DVar.DKind = I->Directive;
1850         DVar.Modifier = Data.Modifier;
1851         DVar.AppliedToPointee = Data.AppliedToPointee;
1852         return DVar;
1853       }
1854     }
1855 
1856     DVar.CKind = OMPC_shared;
1857     return DVar;
1858   }
1859 
1860   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1861   // The predetermined shared attribute for const-qualified types having no
1862   // mutable members was removed after OpenMP 3.1.
1863   if (SemaRef.LangOpts.OpenMP <= 31) {
1864     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1865     // in a Construct, C/C++, predetermined, p.6]
1866     //  Variables with const qualified type having no mutable member are
1867     //  shared.
1868     if (isConstNotMutableType(SemaRef, D->getType())) {
1869       // Variables with const-qualified type having no mutable member may be
1870       // listed in a firstprivate clause, even if they are static data members.
1871       DSAVarData DVarTemp = hasInnermostDSA(
1872           D,
1873           [](OpenMPClauseKind C, bool) {
1874             return C == OMPC_firstprivate || C == OMPC_shared;
1875           },
1876           MatchesAlways, FromParent);
1877       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1878         return DVarTemp;
1879 
1880       DVar.CKind = OMPC_shared;
1881       return DVar;
1882     }
1883   }
1884 
1885   // Explicitly specified attributes and local variables with predetermined
1886   // attributes.
1887   const_iterator I = begin();
1888   const_iterator EndI = end();
1889   if (FromParent && I != EndI)
1890     ++I;
1891   if (I == EndI)
1892     return DVar;
1893   auto It = I->SharingMap.find(D);
1894   if (It != I->SharingMap.end()) {
1895     const DSAInfo &Data = It->getSecond();
1896     DVar.RefExpr = Data.RefExpr.getPointer();
1897     DVar.PrivateCopy = Data.PrivateCopy;
1898     DVar.CKind = Data.Attributes;
1899     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1900     DVar.DKind = I->Directive;
1901     DVar.Modifier = Data.Modifier;
1902     DVar.AppliedToPointee = Data.AppliedToPointee;
1903   }
1904 
1905   return DVar;
1906 }
1907 
getImplicitDSA(ValueDecl * D,bool FromParent) const1908 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1909                                                         bool FromParent) const {
1910   if (isStackEmpty()) {
1911     const_iterator I;
1912     return getDSA(I, D);
1913   }
1914   D = getCanonicalDecl(D);
1915   const_iterator StartI = begin();
1916   const_iterator EndI = end();
1917   if (FromParent && StartI != EndI)
1918     ++StartI;
1919   return getDSA(StartI, D);
1920 }
1921 
getImplicitDSA(ValueDecl * D,unsigned Level) const1922 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1923                                                         unsigned Level) const {
1924   if (getStackSize() <= Level)
1925     return DSAVarData();
1926   D = getCanonicalDecl(D);
1927   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1928   return getDSA(StartI, D);
1929 }
1930 
1931 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool,DefaultDataSharingAttributes)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1932 DSAStackTy::hasDSA(ValueDecl *D,
1933                    const llvm::function_ref<bool(OpenMPClauseKind, bool,
1934                                                  DefaultDataSharingAttributes)>
1935                        CPred,
1936                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1937                    bool FromParent) const {
1938   if (isStackEmpty())
1939     return {};
1940   D = getCanonicalDecl(D);
1941   const_iterator I = begin();
1942   const_iterator EndI = end();
1943   if (FromParent && I != EndI)
1944     ++I;
1945   for (; I != EndI; ++I) {
1946     if (!DPred(I->Directive) &&
1947         !isImplicitOrExplicitTaskingRegion(I->Directive))
1948       continue;
1949     const_iterator NewI = I;
1950     DSAVarData DVar = getDSA(NewI, D);
1951     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1952       return DVar;
1953   }
1954   return {};
1955 }
1956 
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1957 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1958     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1959     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1960     bool FromParent) const {
1961   if (isStackEmpty())
1962     return {};
1963   D = getCanonicalDecl(D);
1964   const_iterator StartI = begin();
1965   const_iterator EndI = end();
1966   if (FromParent && StartI != EndI)
1967     ++StartI;
1968   if (StartI == EndI || !DPred(StartI->Directive))
1969     return {};
1970   const_iterator NewI = StartI;
1971   DSAVarData DVar = getDSA(NewI, D);
1972   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1973              ? DVar
1974              : DSAVarData();
1975 }
1976 
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1977 bool DSAStackTy::hasExplicitDSA(
1978     const ValueDecl *D,
1979     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1980     unsigned Level, bool NotLastprivate) const {
1981   if (getStackSize() <= Level)
1982     return false;
1983   D = getCanonicalDecl(D);
1984   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1985   auto I = StackElem.SharingMap.find(D);
1986   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1987       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1988       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1989     return true;
1990   // Check predetermined rules for the loop control variables.
1991   auto LI = StackElem.LCVMap.find(D);
1992   if (LI != StackElem.LCVMap.end())
1993     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1994   return false;
1995 }
1996 
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1997 bool DSAStackTy::hasExplicitDirective(
1998     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1999     unsigned Level) const {
2000   if (getStackSize() <= Level)
2001     return false;
2002   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2003   return DPred(StackElem.Directive);
2004 }
2005 
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const2006 bool DSAStackTy::hasDirective(
2007     const llvm::function_ref<bool(OpenMPDirectiveKind,
2008                                   const DeclarationNameInfo &, SourceLocation)>
2009         DPred,
2010     bool FromParent) const {
2011   // We look only in the enclosing region.
2012   size_t Skip = FromParent ? 2 : 1;
2013   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2014        I != E; ++I) {
2015     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2016       return true;
2017   }
2018   return false;
2019 }
2020 
InitDataSharingAttributesStack()2021 void Sema::InitDataSharingAttributesStack() {
2022   VarDataSharingAttributesStack = new DSAStackTy(*this);
2023 }
2024 
2025 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2026 
pushOpenMPFunctionRegion()2027 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2028 
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)2029 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2030   DSAStack->popFunction(OldFSI);
2031 }
2032 
isOpenMPDeviceDelayedContext(Sema & S)2033 static bool isOpenMPDeviceDelayedContext(Sema &S) {
2034   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice &&
2035          "Expected OpenMP device compilation.");
2036   return !S.isInOpenMPTargetExecutionDirective();
2037 }
2038 
2039 namespace {
2040 /// Status of the function emission on the host/device.
2041 enum class FunctionEmissionStatus {
2042   Emitted,
2043   Discarded,
2044   Unknown,
2045 };
2046 } // anonymous namespace
2047 
2048 Sema::SemaDiagnosticBuilder
diagIfOpenMPDeviceCode(SourceLocation Loc,unsigned DiagID,const FunctionDecl * FD)2049 Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID,
2050                              const FunctionDecl *FD) {
2051   assert(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice &&
2052          "Expected OpenMP device compilation.");
2053 
2054   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2055   if (FD) {
2056     FunctionEmissionStatus FES = getEmissionStatus(FD);
2057     switch (FES) {
2058     case FunctionEmissionStatus::Emitted:
2059       Kind = SemaDiagnosticBuilder::K_Immediate;
2060       break;
2061     case FunctionEmissionStatus::Unknown:
2062       // TODO: We should always delay diagnostics here in case a target
2063       //       region is in a function we do not emit. However, as the
2064       //       current diagnostics are associated with the function containing
2065       //       the target region and we do not emit that one, we would miss out
2066       //       on diagnostics for the target region itself. We need to anchor
2067       //       the diagnostics with the new generated function *or* ensure we
2068       //       emit diagnostics associated with the surrounding function.
2069       Kind = isOpenMPDeviceDelayedContext(*this)
2070                  ? SemaDiagnosticBuilder::K_Deferred
2071                  : SemaDiagnosticBuilder::K_Immediate;
2072       break;
2073     case FunctionEmissionStatus::TemplateDiscarded:
2074     case FunctionEmissionStatus::OMPDiscarded:
2075       Kind = SemaDiagnosticBuilder::K_Nop;
2076       break;
2077     case FunctionEmissionStatus::CUDADiscarded:
2078       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2079       break;
2080     }
2081   }
2082 
2083   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2084 }
2085 
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID,const FunctionDecl * FD)2086 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2087                                                        unsigned DiagID,
2088                                                        const FunctionDecl *FD) {
2089   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsTargetDevice &&
2090          "Expected OpenMP host compilation.");
2091 
2092   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2093   if (FD) {
2094     FunctionEmissionStatus FES = getEmissionStatus(FD);
2095     switch (FES) {
2096     case FunctionEmissionStatus::Emitted:
2097       Kind = SemaDiagnosticBuilder::K_Immediate;
2098       break;
2099     case FunctionEmissionStatus::Unknown:
2100       Kind = SemaDiagnosticBuilder::K_Deferred;
2101       break;
2102     case FunctionEmissionStatus::TemplateDiscarded:
2103     case FunctionEmissionStatus::OMPDiscarded:
2104     case FunctionEmissionStatus::CUDADiscarded:
2105       Kind = SemaDiagnosticBuilder::K_Nop;
2106       break;
2107     }
2108   }
2109 
2110   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2111 }
2112 
2113 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)2114 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2115   if (LO.OpenMP <= 45) {
2116     if (VD->getType().getNonReferenceType()->isScalarType())
2117       return OMPC_DEFAULTMAP_scalar;
2118     return OMPC_DEFAULTMAP_aggregate;
2119   }
2120   if (VD->getType().getNonReferenceType()->isAnyPointerType())
2121     return OMPC_DEFAULTMAP_pointer;
2122   if (VD->getType().getNonReferenceType()->isScalarType())
2123     return OMPC_DEFAULTMAP_scalar;
2124   return OMPC_DEFAULTMAP_aggregate;
2125 }
2126 
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const2127 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2128                                  unsigned OpenMPCaptureLevel) const {
2129   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2130 
2131   ASTContext &Ctx = getASTContext();
2132   bool IsByRef = true;
2133 
2134   // Find the directive that is associated with the provided scope.
2135   D = cast<ValueDecl>(D->getCanonicalDecl());
2136   QualType Ty = D->getType();
2137 
2138   bool IsVariableUsedInMapClause = false;
2139   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2140     // This table summarizes how a given variable should be passed to the device
2141     // given its type and the clauses where it appears. This table is based on
2142     // the description in OpenMP 4.5 [2.10.4, target Construct] and
2143     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2144     //
2145     // =========================================================================
2146     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2147     // |      |(tofrom:scalar)|     |  pvt  |               |has_dv_adr|       |
2148     // =========================================================================
2149     // | scl  |               |     |       |       -       |          | bycopy|
2150     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2151     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2152     // | scl  |       x       |     |       |       -       |          | byref |
2153     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2154     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2155     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2156     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2157     //
2158     // | agg  |      n.a.     |     |       |       -       |          | byref |
2159     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2160     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2161     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2162     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2163     //
2164     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2165     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2166     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2167     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2168     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2169     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2170     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2171     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2172     // =========================================================================
2173     // Legend:
2174     //  scl - scalar
2175     //  ptr - pointer
2176     //  agg - aggregate
2177     //  x - applies
2178     //  - - invalid in this combination
2179     //  [] - mapped with an array section
2180     //  byref - should be mapped by reference
2181     //  byval - should be mapped by value
2182     //  null - initialize a local variable to null on the device
2183     //
2184     // Observations:
2185     //  - All scalar declarations that show up in a map clause have to be passed
2186     //    by reference, because they may have been mapped in the enclosing data
2187     //    environment.
2188     //  - If the scalar value does not fit the size of uintptr, it has to be
2189     //    passed by reference, regardless the result in the table above.
2190     //  - For pointers mapped by value that have either an implicit map or an
2191     //    array section, the runtime library may pass the NULL value to the
2192     //    device instead of the value passed to it by the compiler.
2193 
2194     if (Ty->isReferenceType())
2195       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2196 
2197     // Locate map clauses and see if the variable being captured is referred to
2198     // in any of those clauses. Here we only care about variables, not fields,
2199     // because fields are part of aggregates.
2200     bool IsVariableAssociatedWithSection = false;
2201 
2202     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2203         D, Level,
2204         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2205          D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2206                 MapExprComponents,
2207             OpenMPClauseKind WhereFoundClauseKind) {
2208           // Both map and has_device_addr clauses information influences how a
2209           // variable is captured. E.g. is_device_ptr does not require changing
2210           // the default behavior.
2211           if (WhereFoundClauseKind != OMPC_map &&
2212               WhereFoundClauseKind != OMPC_has_device_addr)
2213             return false;
2214 
2215           auto EI = MapExprComponents.rbegin();
2216           auto EE = MapExprComponents.rend();
2217 
2218           assert(EI != EE && "Invalid map expression!");
2219 
2220           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2221             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2222 
2223           ++EI;
2224           if (EI == EE)
2225             return false;
2226           auto Last = std::prev(EE);
2227           const auto *UO =
2228               dyn_cast<UnaryOperator>(Last->getAssociatedExpression());
2229           if ((UO && UO->getOpcode() == UO_Deref) ||
2230               isa<ArraySubscriptExpr>(Last->getAssociatedExpression()) ||
2231               isa<OMPArraySectionExpr>(Last->getAssociatedExpression()) ||
2232               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2233               isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())) {
2234             IsVariableAssociatedWithSection = true;
2235             // There is nothing more we need to know about this variable.
2236             return true;
2237           }
2238 
2239           // Keep looking for more map info.
2240           return false;
2241         });
2242 
2243     if (IsVariableUsedInMapClause) {
2244       // If variable is identified in a map clause it is always captured by
2245       // reference except if it is a pointer that is dereferenced somehow.
2246       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2247     } else {
2248       // By default, all the data that has a scalar type is mapped by copy
2249       // (except for reduction variables).
2250       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2251       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2252                  !Ty->isAnyPointerType()) ||
2253                 !Ty->isScalarType() ||
2254                 DSAStack->isDefaultmapCapturedByRef(
2255                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2256                 DSAStack->hasExplicitDSA(
2257                     D,
2258                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2259                       return K == OMPC_reduction && !AppliedToPointee;
2260                     },
2261                     Level);
2262     }
2263   }
2264 
2265   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2266     IsByRef =
2267         ((IsVariableUsedInMapClause &&
2268           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2269               OMPD_target) ||
2270          !(DSAStack->hasExplicitDSA(
2271                D,
2272                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2273                  return K == OMPC_firstprivate ||
2274                         (K == OMPC_reduction && AppliedToPointee);
2275                },
2276                Level, /*NotLastprivate=*/true) ||
2277            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2278         // If the variable is artificial and must be captured by value - try to
2279         // capture by value.
2280         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2281           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2282         // If the variable is implicitly firstprivate and scalar - capture by
2283         // copy
2284         !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2285            DSAStack->getDefaultDSA() == DSA_private) &&
2286           !DSAStack->hasExplicitDSA(
2287               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2288               Level) &&
2289           !DSAStack->isLoopControlVariable(D, Level).first);
2290   }
2291 
2292   // When passing data by copy, we need to make sure it fits the uintptr size
2293   // and alignment, because the runtime library only deals with uintptr types.
2294   // If it does not fit the uintptr size, we need to pass the data by reference
2295   // instead.
2296   if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
2297                        Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2298                    Ctx.getAlignOfGlobalVarInChars(Ty) >
2299                        Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2300     IsByRef = true;
2301   }
2302 
2303   return IsByRef;
2304 }
2305 
getOpenMPNestingLevel() const2306 unsigned Sema::getOpenMPNestingLevel() const {
2307   assert(getLangOpts().OpenMP);
2308   return DSAStack->getNestingLevel();
2309 }
2310 
isInOpenMPTaskUntiedContext() const2311 bool Sema::isInOpenMPTaskUntiedContext() const {
2312   return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2313          DSAStack->isUntiedRegion();
2314 }
2315 
isInOpenMPTargetExecutionDirective() const2316 bool Sema::isInOpenMPTargetExecutionDirective() const {
2317   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2318           !DSAStack->isClauseParsingMode()) ||
2319          DSAStack->hasDirective(
2320              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2321                 SourceLocation) -> bool {
2322                return isOpenMPTargetExecutionDirective(K);
2323              },
2324              false);
2325 }
2326 
isOpenMPRebuildMemberExpr(ValueDecl * D)2327 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2328   // Only rebuild for Field.
2329   if (!dyn_cast<FieldDecl>(D))
2330     return false;
2331   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2332       D,
2333       [](OpenMPClauseKind C, bool AppliedToPointee,
2334          DefaultDataSharingAttributes DefaultAttr) {
2335         return isOpenMPPrivate(C) && !AppliedToPointee &&
2336                (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2337       },
2338       [](OpenMPDirectiveKind) { return true; },
2339       DSAStack->isClauseParsingMode());
2340   if (DVarPrivate.CKind != OMPC_unknown)
2341     return true;
2342   return false;
2343 }
2344 
2345 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2346                                              Expr *CaptureExpr, bool WithInit,
2347                                              DeclContext *CurContext,
2348                                              bool AsExpression);
2349 
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2350 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2351                                     unsigned StopAt) {
2352   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2353   D = getCanonicalDecl(D);
2354 
2355   auto *VD = dyn_cast<VarDecl>(D);
2356   // Do not capture constexpr variables.
2357   if (VD && VD->isConstexpr())
2358     return nullptr;
2359 
2360   // If we want to determine whether the variable should be captured from the
2361   // perspective of the current capturing scope, and we've already left all the
2362   // capturing scopes of the top directive on the stack, check from the
2363   // perspective of its parent directive (if any) instead.
2364   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2365       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2366 
2367   // If we are attempting to capture a global variable in a directive with
2368   // 'target' we return true so that this global is also mapped to the device.
2369   //
2370   if (VD && !VD->hasLocalStorage() &&
2371       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2372     if (isInOpenMPTargetExecutionDirective()) {
2373       DSAStackTy::DSAVarData DVarTop =
2374           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2375       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2376         return VD;
2377       // If the declaration is enclosed in a 'declare target' directive,
2378       // then it should not be captured.
2379       //
2380       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2381         return nullptr;
2382       CapturedRegionScopeInfo *CSI = nullptr;
2383       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2384                llvm::reverse(FunctionScopes),
2385                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2386         if (!isa<CapturingScopeInfo>(FSI))
2387           return nullptr;
2388         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2389           if (RSI->CapRegionKind == CR_OpenMP) {
2390             CSI = RSI;
2391             break;
2392           }
2393       }
2394       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2395       SmallVector<OpenMPDirectiveKind, 4> Regions;
2396       getOpenMPCaptureRegions(Regions,
2397                               DSAStack->getDirective(CSI->OpenMPLevel));
2398       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2399         return VD;
2400     }
2401     if (isInOpenMPDeclareTargetContext()) {
2402       // Try to mark variable as declare target if it is used in capturing
2403       // regions.
2404       if (LangOpts.OpenMP <= 45 &&
2405           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2406         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2407       return nullptr;
2408     }
2409   }
2410 
2411   if (CheckScopeInfo) {
2412     bool OpenMPFound = false;
2413     for (unsigned I = StopAt + 1; I > 0; --I) {
2414       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2415       if (!isa<CapturingScopeInfo>(FSI))
2416         return nullptr;
2417       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2418         if (RSI->CapRegionKind == CR_OpenMP) {
2419           OpenMPFound = true;
2420           break;
2421         }
2422     }
2423     if (!OpenMPFound)
2424       return nullptr;
2425   }
2426 
2427   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2428       (!DSAStack->isClauseParsingMode() ||
2429        DSAStack->getParentDirective() != OMPD_unknown)) {
2430     auto &&Info = DSAStack->isLoopControlVariable(D);
2431     if (Info.first ||
2432         (VD && VD->hasLocalStorage() &&
2433          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2434         (VD && DSAStack->isForceVarCapturing()))
2435       return VD ? VD : Info.second;
2436     DSAStackTy::DSAVarData DVarTop =
2437         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2438     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2439         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2440       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2441     // Threadprivate variables must not be captured.
2442     if (isOpenMPThreadPrivate(DVarTop.CKind))
2443       return nullptr;
2444     // The variable is not private or it is the variable in the directive with
2445     // default(none) clause and not used in any clause.
2446     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2447         D,
2448         [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2449           return isOpenMPPrivate(C) && !AppliedToPointee;
2450         },
2451         [](OpenMPDirectiveKind) { return true; },
2452         DSAStack->isClauseParsingMode());
2453     // Global shared must not be captured.
2454     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2455         ((DSAStack->getDefaultDSA() != DSA_none &&
2456           DSAStack->getDefaultDSA() != DSA_private &&
2457           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2458          DVarTop.CKind == OMPC_shared))
2459       return nullptr;
2460     auto *FD = dyn_cast<FieldDecl>(D);
2461     if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2462         !DVarPrivate.PrivateCopy) {
2463       DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2464           D,
2465           [](OpenMPClauseKind C, bool AppliedToPointee,
2466              DefaultDataSharingAttributes DefaultAttr) {
2467             return isOpenMPPrivate(C) && !AppliedToPointee &&
2468                    (DefaultAttr == DSA_firstprivate ||
2469                     DefaultAttr == DSA_private);
2470           },
2471           [](OpenMPDirectiveKind) { return true; },
2472           DSAStack->isClauseParsingMode());
2473       if (DVarPrivate.CKind == OMPC_unknown)
2474         return nullptr;
2475 
2476       VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2477       if (VD)
2478         return VD;
2479       if (getCurrentThisType().isNull())
2480         return nullptr;
2481       Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2482                                         /*IsImplicit=*/true);
2483       const CXXScopeSpec CS = CXXScopeSpec();
2484       Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2485                                  NestedNameSpecifierLoc(), SourceLocation(), FD,
2486                                  DeclAccessPair::make(FD, FD->getAccess()),
2487                                  /*HadMultipleCandidates=*/false,
2488                                  DeclarationNameInfo(), FD->getType(),
2489                                  VK_LValue, OK_Ordinary);
2490       OMPCapturedExprDecl *CD = buildCaptureDecl(
2491           *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2492           CurContext->getParent(), /*AsExpression=*/false);
2493       DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2494           *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2495       VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2496       DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2497       return VD;
2498     }
2499     if (DVarPrivate.CKind != OMPC_unknown ||
2500         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2501                 DSAStack->getDefaultDSA() == DSA_private ||
2502                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2503       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2504   }
2505   return nullptr;
2506 }
2507 
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2508 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2509                                         unsigned Level) const {
2510   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2511 }
2512 
startOpenMPLoop()2513 void Sema::startOpenMPLoop() {
2514   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2515   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2516     DSAStack->loopInit();
2517 }
2518 
startOpenMPCXXRangeFor()2519 void Sema::startOpenMPCXXRangeFor() {
2520   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2521   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2522     DSAStack->resetPossibleLoopCounter();
2523     DSAStack->loopStart();
2524   }
2525 }
2526 
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2527 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2528                                            unsigned CapLevel) const {
2529   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2530   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2531       (!DSAStack->isClauseParsingMode() ||
2532        DSAStack->getParentDirective() != OMPD_unknown)) {
2533     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2534         D,
2535         [](OpenMPClauseKind C, bool AppliedToPointee,
2536            DefaultDataSharingAttributes DefaultAttr) {
2537           return isOpenMPPrivate(C) && !AppliedToPointee &&
2538                  DefaultAttr == DSA_private;
2539         },
2540         [](OpenMPDirectiveKind) { return true; },
2541         DSAStack->isClauseParsingMode());
2542     if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2543         DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2544         !DSAStack->isLoopControlVariable(D).first)
2545       return OMPC_private;
2546   }
2547   if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2548     bool IsTriviallyCopyable =
2549         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2550         !D->getType()
2551              .getNonReferenceType()
2552              .getCanonicalType()
2553              ->getAsCXXRecordDecl();
2554     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2555     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2556     getOpenMPCaptureRegions(CaptureRegions, DKind);
2557     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2558         (IsTriviallyCopyable ||
2559          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2560       if (DSAStack->hasExplicitDSA(
2561               D,
2562               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2563               Level, /*NotLastprivate=*/true))
2564         return OMPC_firstprivate;
2565       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2566       if (DVar.CKind != OMPC_shared &&
2567           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2568         DSAStack->addImplicitTaskFirstprivate(Level, D);
2569         return OMPC_firstprivate;
2570       }
2571     }
2572   }
2573   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) &&
2574       !isOpenMPLoopTransformationDirective(DSAStack->getCurrentDirective())) {
2575     if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2576       DSAStack->resetPossibleLoopCounter(D);
2577       DSAStack->loopStart();
2578       return OMPC_private;
2579     }
2580     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2581          DSAStack->isLoopControlVariable(D).first) &&
2582         !DSAStack->hasExplicitDSA(
2583             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2584             Level) &&
2585         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2586       return OMPC_private;
2587   }
2588   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2589     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2590         DSAStack->isForceVarCapturing() &&
2591         !DSAStack->hasExplicitDSA(
2592             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2593             Level))
2594       return OMPC_private;
2595   }
2596   // User-defined allocators are private since they must be defined in the
2597   // context of target region.
2598   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2599       DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2600           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2601           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2602     return OMPC_private;
2603   return (DSAStack->hasExplicitDSA(
2604               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2605               Level) ||
2606           (DSAStack->isClauseParsingMode() &&
2607            DSAStack->getClauseParsingMode() == OMPC_private) ||
2608           // Consider taskgroup reduction descriptor variable a private
2609           // to avoid possible capture in the region.
2610           (DSAStack->hasExplicitDirective(
2611                [](OpenMPDirectiveKind K) {
2612                  return K == OMPD_taskgroup ||
2613                         ((isOpenMPParallelDirective(K) ||
2614                           isOpenMPWorksharingDirective(K)) &&
2615                          !isOpenMPSimdDirective(K));
2616                },
2617                Level) &&
2618            DSAStack->isTaskgroupReductionRef(D, Level)))
2619              ? OMPC_private
2620              : OMPC_unknown;
2621 }
2622 
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2623 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2624                                 unsigned Level) {
2625   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2626   D = getCanonicalDecl(D);
2627   OpenMPClauseKind OMPC = OMPC_unknown;
2628   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2629     const unsigned NewLevel = I - 1;
2630     if (DSAStack->hasExplicitDSA(
2631             D,
2632             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2633               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2634                 OMPC = K;
2635                 return true;
2636               }
2637               return false;
2638             },
2639             NewLevel))
2640       break;
2641     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2642             D, NewLevel,
2643             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2644                OpenMPClauseKind) { return true; })) {
2645       OMPC = OMPC_map;
2646       break;
2647     }
2648     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2649                                        NewLevel)) {
2650       OMPC = OMPC_map;
2651       if (DSAStack->mustBeFirstprivateAtLevel(
2652               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2653         OMPC = OMPC_firstprivate;
2654       break;
2655     }
2656   }
2657   if (OMPC != OMPC_unknown)
2658     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2659 }
2660 
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2661 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2662                                       unsigned CaptureLevel) const {
2663   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2664   // Return true if the current level is no longer enclosed in a target region.
2665 
2666   SmallVector<OpenMPDirectiveKind, 4> Regions;
2667   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2668   const auto *VD = dyn_cast<VarDecl>(D);
2669   return VD && !VD->hasLocalStorage() &&
2670          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2671                                         Level) &&
2672          Regions[CaptureLevel] != OMPD_task;
2673 }
2674 
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2675 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2676                                       unsigned CaptureLevel) const {
2677   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2678   // Return true if the current level is no longer enclosed in a target region.
2679 
2680   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2681     if (!VD->hasLocalStorage()) {
2682       if (isInOpenMPTargetExecutionDirective())
2683         return true;
2684       DSAStackTy::DSAVarData TopDVar =
2685           DSAStack->getTopDSA(D, /*FromParent=*/false);
2686       unsigned NumLevels =
2687           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2688       if (Level == 0)
2689         // non-file scope static variale with default(firstprivate)
2690         // should be gloabal captured.
2691         return (NumLevels == CaptureLevel + 1 &&
2692                 (TopDVar.CKind != OMPC_shared ||
2693                  DSAStack->getDefaultDSA() == DSA_firstprivate));
2694       do {
2695         --Level;
2696         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2697         if (DVar.CKind != OMPC_shared)
2698           return true;
2699       } while (Level > 0);
2700     }
2701   }
2702   return true;
2703 }
2704 
DestroyDataSharingAttributesStack()2705 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2706 
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2707 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2708                                           OMPTraitInfo &TI) {
2709   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2710 }
2711 
ActOnOpenMPEndDeclareVariant()2712 void Sema::ActOnOpenMPEndDeclareVariant() {
2713   assert(isInOpenMPDeclareVariantScope() &&
2714          "Not in OpenMP declare variant scope!");
2715 
2716   OMPDeclareVariantScopes.pop_back();
2717 }
2718 
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2719 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2720                                          const FunctionDecl *Callee,
2721                                          SourceLocation Loc) {
2722   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2723   std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2724       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2725   // Ignore host functions during device analyzis.
2726   if (LangOpts.OpenMPIsTargetDevice &&
2727       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2728     return;
2729   // Ignore nohost functions during host analyzis.
2730   if (!LangOpts.OpenMPIsTargetDevice && DevTy &&
2731       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2732     return;
2733   const FunctionDecl *FD = Callee->getMostRecentDecl();
2734   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2735   if (LangOpts.OpenMPIsTargetDevice && DevTy &&
2736       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2737     // Diagnose host function called during device codegen.
2738     StringRef HostDevTy =
2739         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2740     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2741     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2742          diag::note_omp_marked_device_type_here)
2743         << HostDevTy;
2744     return;
2745   }
2746   if (!LangOpts.OpenMPIsTargetDevice && !LangOpts.OpenMPOffloadMandatory &&
2747       DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2748     // In OpenMP 5.2 or later, if the function has a host variant then allow
2749     // that to be called instead
2750     auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2751       for (OMPDeclareVariantAttr *A :
2752            Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2753         auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2754         auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2755         std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2756             OMPDeclareTargetDeclAttr::getDeviceType(
2757                 VariantFD->getMostRecentDecl());
2758         if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2759           return true;
2760       }
2761       return false;
2762     };
2763     if (getLangOpts().OpenMP >= 52 &&
2764         Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2765       return;
2766     // Diagnose nohost function called during host codegen.
2767     StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2768         OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2769     Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2770     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2771          diag::note_omp_marked_device_type_here)
2772         << NoHostDevTy;
2773   }
2774 }
2775 
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2776 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2777                                const DeclarationNameInfo &DirName,
2778                                Scope *CurScope, SourceLocation Loc) {
2779   DSAStack->push(DKind, DirName, CurScope, Loc);
2780   PushExpressionEvaluationContext(
2781       ExpressionEvaluationContext::PotentiallyEvaluated);
2782 }
2783 
StartOpenMPClause(OpenMPClauseKind K)2784 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2785   DSAStack->setClauseParsingMode(K);
2786 }
2787 
EndOpenMPClause()2788 void Sema::EndOpenMPClause() {
2789   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2790   CleanupVarDeclMarking();
2791 }
2792 
2793 static std::pair<ValueDecl *, bool>
2794 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2795                SourceRange &ERange, bool AllowArraySection = false,
2796                StringRef DiagType = "");
2797 
2798 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2799 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2800                                   ArrayRef<OMPClause *> Clauses) {
2801   bool InscanFound = false;
2802   SourceLocation InscanLoc;
2803   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2804   // A reduction clause without the inscan reduction-modifier may not appear on
2805   // a construct on which a reduction clause with the inscan reduction-modifier
2806   // appears.
2807   for (OMPClause *C : Clauses) {
2808     if (C->getClauseKind() != OMPC_reduction)
2809       continue;
2810     auto *RC = cast<OMPReductionClause>(C);
2811     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2812       InscanFound = true;
2813       InscanLoc = RC->getModifierLoc();
2814       continue;
2815     }
2816     if (RC->getModifier() == OMPC_REDUCTION_task) {
2817       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2818       // A reduction clause with the task reduction-modifier may only appear on
2819       // a parallel construct, a worksharing construct or a combined or
2820       // composite construct for which any of the aforementioned constructs is a
2821       // constituent construct and simd or loop are not constituent constructs.
2822       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2823       if (!(isOpenMPParallelDirective(CurDir) ||
2824             isOpenMPWorksharingDirective(CurDir)) ||
2825           isOpenMPSimdDirective(CurDir))
2826         S.Diag(RC->getModifierLoc(),
2827                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2828       continue;
2829     }
2830   }
2831   if (InscanFound) {
2832     for (OMPClause *C : Clauses) {
2833       if (C->getClauseKind() != OMPC_reduction)
2834         continue;
2835       auto *RC = cast<OMPReductionClause>(C);
2836       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2837         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2838                    ? RC->getBeginLoc()
2839                    : RC->getModifierLoc(),
2840                diag::err_omp_inscan_reduction_expected);
2841         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2842         continue;
2843       }
2844       for (Expr *Ref : RC->varlists()) {
2845         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2846         SourceLocation ELoc;
2847         SourceRange ERange;
2848         Expr *SimpleRefExpr = Ref;
2849         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2850                                   /*AllowArraySection=*/true);
2851         ValueDecl *D = Res.first;
2852         if (!D)
2853           continue;
2854         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2855           S.Diag(Ref->getExprLoc(),
2856                  diag::err_omp_reduction_not_inclusive_exclusive)
2857               << Ref->getSourceRange();
2858         }
2859       }
2860     }
2861   }
2862 }
2863 
2864 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2865                                  ArrayRef<OMPClause *> Clauses);
2866 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2867                                  bool WithInit);
2868 
2869 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2870                               const ValueDecl *D,
2871                               const DSAStackTy::DSAVarData &DVar,
2872                               bool IsLoopIterVar = false);
2873 
EndOpenMPDSABlock(Stmt * CurDirective)2874 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2875   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2876   //  A variable of class type (or array thereof) that appears in a lastprivate
2877   //  clause requires an accessible, unambiguous default constructor for the
2878   //  class type, unless the list item is also specified in a firstprivate
2879   //  clause.
2880   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2881     for (OMPClause *C : D->clauses()) {
2882       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2883         SmallVector<Expr *, 8> PrivateCopies;
2884         for (Expr *DE : Clause->varlists()) {
2885           if (DE->isValueDependent() || DE->isTypeDependent()) {
2886             PrivateCopies.push_back(nullptr);
2887             continue;
2888           }
2889           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2890           auto *VD = cast<VarDecl>(DRE->getDecl());
2891           QualType Type = VD->getType().getNonReferenceType();
2892           const DSAStackTy::DSAVarData DVar =
2893               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2894           if (DVar.CKind == OMPC_lastprivate) {
2895             // Generate helper private variable and initialize it with the
2896             // default value. The address of the original variable is replaced
2897             // by the address of the new private variable in CodeGen. This new
2898             // variable is not added to IdResolver, so the code in the OpenMP
2899             // region uses original variable for proper diagnostics.
2900             VarDecl *VDPrivate = buildVarDecl(
2901                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2902                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2903             ActOnUninitializedDecl(VDPrivate);
2904             if (VDPrivate->isInvalidDecl()) {
2905               PrivateCopies.push_back(nullptr);
2906               continue;
2907             }
2908             PrivateCopies.push_back(buildDeclRefExpr(
2909                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2910           } else {
2911             // The variable is also a firstprivate, so initialization sequence
2912             // for private copy is generated already.
2913             PrivateCopies.push_back(nullptr);
2914           }
2915         }
2916         Clause->setPrivateCopies(PrivateCopies);
2917         continue;
2918       }
2919       // Finalize nontemporal clause by handling private copies, if any.
2920       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2921         SmallVector<Expr *, 8> PrivateRefs;
2922         for (Expr *RefExpr : Clause->varlists()) {
2923           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2924           SourceLocation ELoc;
2925           SourceRange ERange;
2926           Expr *SimpleRefExpr = RefExpr;
2927           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2928           if (Res.second)
2929             // It will be analyzed later.
2930             PrivateRefs.push_back(RefExpr);
2931           ValueDecl *D = Res.first;
2932           if (!D)
2933             continue;
2934 
2935           const DSAStackTy::DSAVarData DVar =
2936               DSAStack->getTopDSA(D, /*FromParent=*/false);
2937           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2938                                                  : SimpleRefExpr);
2939         }
2940         Clause->setPrivateRefs(PrivateRefs);
2941         continue;
2942       }
2943       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2944         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2945           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2946           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2947           if (!DRE)
2948             continue;
2949           ValueDecl *VD = DRE->getDecl();
2950           if (!VD || !isa<VarDecl>(VD))
2951             continue;
2952           DSAStackTy::DSAVarData DVar =
2953               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2954           // OpenMP [2.12.5, target Construct]
2955           // Memory allocators that appear in a uses_allocators clause cannot
2956           // appear in other data-sharing attribute clauses or data-mapping
2957           // attribute clauses in the same construct.
2958           Expr *MapExpr = nullptr;
2959           if (DVar.RefExpr ||
2960               DSAStack->checkMappableExprComponentListsForDecl(
2961                   VD, /*CurrentRegionOnly=*/true,
2962                   [VD, &MapExpr](
2963                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2964                           MapExprComponents,
2965                       OpenMPClauseKind C) {
2966                     auto MI = MapExprComponents.rbegin();
2967                     auto ME = MapExprComponents.rend();
2968                     if (MI != ME &&
2969                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2970                             VD->getCanonicalDecl()) {
2971                       MapExpr = MI->getAssociatedExpression();
2972                       return true;
2973                     }
2974                     return false;
2975                   })) {
2976             Diag(D.Allocator->getExprLoc(),
2977                  diag::err_omp_allocator_used_in_clauses)
2978                 << D.Allocator->getSourceRange();
2979             if (DVar.RefExpr)
2980               reportOriginalDsa(*this, DSAStack, VD, DVar);
2981             else
2982               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2983                   << MapExpr->getSourceRange();
2984           }
2985         }
2986         continue;
2987       }
2988     }
2989     // Check allocate clauses.
2990     if (!CurContext->isDependentContext())
2991       checkAllocateClauses(*this, DSAStack, D->clauses());
2992     checkReductionClauses(*this, DSAStack, D->clauses());
2993   }
2994 
2995   DSAStack->pop();
2996   DiscardCleanupsInEvaluationContext();
2997   PopExpressionEvaluationContext();
2998 }
2999 
3000 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
3001                                      Expr *NumIterations, Sema &SemaRef,
3002                                      Scope *S, DSAStackTy *Stack);
3003 
3004 namespace {
3005 
3006 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
3007 private:
3008   Sema &SemaRef;
3009 
3010 public:
VarDeclFilterCCC(Sema & S)3011   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)3012   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3013     NamedDecl *ND = Candidate.getCorrectionDecl();
3014     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3015       return VD->hasGlobalStorage() &&
3016              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3017                                    SemaRef.getCurScope());
3018     }
3019     return false;
3020   }
3021 
clone()3022   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3023     return std::make_unique<VarDeclFilterCCC>(*this);
3024   }
3025 };
3026 
3027 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3028 private:
3029   Sema &SemaRef;
3030 
3031 public:
VarOrFuncDeclFilterCCC(Sema & S)3032   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)3033   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3034     NamedDecl *ND = Candidate.getCorrectionDecl();
3035     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
3036                isa<FunctionDecl>(ND))) {
3037       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3038                                    SemaRef.getCurScope());
3039     }
3040     return false;
3041   }
3042 
clone()3043   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3044     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3045   }
3046 };
3047 
3048 } // namespace
3049 
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)3050 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3051                                          CXXScopeSpec &ScopeSpec,
3052                                          const DeclarationNameInfo &Id,
3053                                          OpenMPDirectiveKind Kind) {
3054   LookupResult Lookup(*this, Id, LookupOrdinaryName);
3055   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3056 
3057   if (Lookup.isAmbiguous())
3058     return ExprError();
3059 
3060   VarDecl *VD;
3061   if (!Lookup.isSingleResult()) {
3062     VarDeclFilterCCC CCC(*this);
3063     if (TypoCorrection Corrected =
3064             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3065                         CTK_ErrorRecovery)) {
3066       diagnoseTypo(Corrected,
3067                    PDiag(Lookup.empty()
3068                              ? diag::err_undeclared_var_use_suggest
3069                              : diag::err_omp_expected_var_arg_suggest)
3070                        << Id.getName());
3071       VD = Corrected.getCorrectionDeclAs<VarDecl>();
3072     } else {
3073       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3074                                        : diag::err_omp_expected_var_arg)
3075           << Id.getName();
3076       return ExprError();
3077     }
3078   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3079     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3080     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3081     return ExprError();
3082   }
3083   Lookup.suppressDiagnostics();
3084 
3085   // OpenMP [2.9.2, Syntax, C/C++]
3086   //   Variables must be file-scope, namespace-scope, or static block-scope.
3087   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3088     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3089         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3090     bool IsDecl =
3091         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3092     Diag(VD->getLocation(),
3093          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3094         << VD;
3095     return ExprError();
3096   }
3097 
3098   VarDecl *CanonicalVD = VD->getCanonicalDecl();
3099   NamedDecl *ND = CanonicalVD;
3100   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3101   //   A threadprivate directive for file-scope variables must appear outside
3102   //   any definition or declaration.
3103   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3104       !getCurLexicalContext()->isTranslationUnit()) {
3105     Diag(Id.getLoc(), diag::err_omp_var_scope)
3106         << getOpenMPDirectiveName(Kind) << VD;
3107     bool IsDecl =
3108         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3109     Diag(VD->getLocation(),
3110          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3111         << VD;
3112     return ExprError();
3113   }
3114   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3115   //   A threadprivate directive for static class member variables must appear
3116   //   in the class definition, in the same scope in which the member
3117   //   variables are declared.
3118   if (CanonicalVD->isStaticDataMember() &&
3119       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3120     Diag(Id.getLoc(), diag::err_omp_var_scope)
3121         << getOpenMPDirectiveName(Kind) << VD;
3122     bool IsDecl =
3123         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3124     Diag(VD->getLocation(),
3125          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3126         << VD;
3127     return ExprError();
3128   }
3129   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3130   //   A threadprivate directive for namespace-scope variables must appear
3131   //   outside any definition or declaration other than the namespace
3132   //   definition itself.
3133   if (CanonicalVD->getDeclContext()->isNamespace() &&
3134       (!getCurLexicalContext()->isFileContext() ||
3135        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3136     Diag(Id.getLoc(), diag::err_omp_var_scope)
3137         << getOpenMPDirectiveName(Kind) << VD;
3138     bool IsDecl =
3139         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3140     Diag(VD->getLocation(),
3141          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3142         << VD;
3143     return ExprError();
3144   }
3145   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3146   //   A threadprivate directive for static block-scope variables must appear
3147   //   in the scope of the variable and not in a nested scope.
3148   if (CanonicalVD->isLocalVarDecl() && CurScope &&
3149       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3150     Diag(Id.getLoc(), diag::err_omp_var_scope)
3151         << getOpenMPDirectiveName(Kind) << VD;
3152     bool IsDecl =
3153         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3154     Diag(VD->getLocation(),
3155          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3156         << VD;
3157     return ExprError();
3158   }
3159 
3160   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3161   //   A threadprivate directive must lexically precede all references to any
3162   //   of the variables in its list.
3163   if (Kind == OMPD_threadprivate && VD->isUsed() &&
3164       !DSAStack->isThreadPrivate(VD)) {
3165     Diag(Id.getLoc(), diag::err_omp_var_used)
3166         << getOpenMPDirectiveName(Kind) << VD;
3167     return ExprError();
3168   }
3169 
3170   QualType ExprType = VD->getType().getNonReferenceType();
3171   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3172                              SourceLocation(), VD,
3173                              /*RefersToEnclosingVariableOrCapture=*/false,
3174                              Id.getLoc(), ExprType, VK_LValue);
3175 }
3176 
3177 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)3178 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3179                                         ArrayRef<Expr *> VarList) {
3180   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3181     CurContext->addDecl(D);
3182     return DeclGroupPtrTy::make(DeclGroupRef(D));
3183   }
3184   return nullptr;
3185 }
3186 
3187 namespace {
3188 class LocalVarRefChecker final
3189     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3190   Sema &SemaRef;
3191 
3192 public:
VisitDeclRefExpr(const DeclRefExpr * E)3193   bool VisitDeclRefExpr(const DeclRefExpr *E) {
3194     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3195       if (VD->hasLocalStorage()) {
3196         SemaRef.Diag(E->getBeginLoc(),
3197                      diag::err_omp_local_var_in_threadprivate_init)
3198             << E->getSourceRange();
3199         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3200             << VD << VD->getSourceRange();
3201         return true;
3202       }
3203     }
3204     return false;
3205   }
VisitStmt(const Stmt * S)3206   bool VisitStmt(const Stmt *S) {
3207     for (const Stmt *Child : S->children()) {
3208       if (Child && Visit(Child))
3209         return true;
3210     }
3211     return false;
3212   }
LocalVarRefChecker(Sema & SemaRef)3213   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3214 };
3215 } // namespace
3216 
3217 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)3218 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3219   SmallVector<Expr *, 8> Vars;
3220   for (Expr *RefExpr : VarList) {
3221     auto *DE = cast<DeclRefExpr>(RefExpr);
3222     auto *VD = cast<VarDecl>(DE->getDecl());
3223     SourceLocation ILoc = DE->getExprLoc();
3224 
3225     // Mark variable as used.
3226     VD->setReferenced();
3227     VD->markUsed(Context);
3228 
3229     QualType QType = VD->getType();
3230     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3231       // It will be analyzed later.
3232       Vars.push_back(DE);
3233       continue;
3234     }
3235 
3236     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3237     //   A threadprivate variable must not have an incomplete type.
3238     if (RequireCompleteType(ILoc, VD->getType(),
3239                             diag::err_omp_threadprivate_incomplete_type)) {
3240       continue;
3241     }
3242 
3243     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3244     //   A threadprivate variable must not have a reference type.
3245     if (VD->getType()->isReferenceType()) {
3246       Diag(ILoc, diag::err_omp_ref_type_arg)
3247           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3248       bool IsDecl =
3249           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3250       Diag(VD->getLocation(),
3251            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3252           << VD;
3253       continue;
3254     }
3255 
3256     // Check if this is a TLS variable. If TLS is not being supported, produce
3257     // the corresponding diagnostic.
3258     if ((VD->getTLSKind() != VarDecl::TLS_None &&
3259          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3260            getLangOpts().OpenMPUseTLS &&
3261            getASTContext().getTargetInfo().isTLSSupported())) ||
3262         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3263          !VD->isLocalVarDecl())) {
3264       Diag(ILoc, diag::err_omp_var_thread_local)
3265           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3266       bool IsDecl =
3267           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3268       Diag(VD->getLocation(),
3269            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3270           << VD;
3271       continue;
3272     }
3273 
3274     // Check if initial value of threadprivate variable reference variable with
3275     // local storage (it is not supported by runtime).
3276     if (const Expr *Init = VD->getAnyInitializer()) {
3277       LocalVarRefChecker Checker(*this);
3278       if (Checker.Visit(Init))
3279         continue;
3280     }
3281 
3282     Vars.push_back(RefExpr);
3283     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3284     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3285         Context, SourceRange(Loc, Loc)));
3286     if (ASTMutationListener *ML = Context.getASTMutationListener())
3287       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3288   }
3289   OMPThreadPrivateDecl *D = nullptr;
3290   if (!Vars.empty()) {
3291     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3292                                      Vars);
3293     D->setAccess(AS_public);
3294   }
3295   return D;
3296 }
3297 
3298 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3299 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3300   if (!Allocator)
3301     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3302   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3303       Allocator->isInstantiationDependent() ||
3304       Allocator->containsUnexpandedParameterPack())
3305     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3306   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3307   llvm::FoldingSetNodeID AEId;
3308   const Expr *AE = Allocator->IgnoreParenImpCasts();
3309   AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3310   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3311     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3312     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3313     llvm::FoldingSetNodeID DAEId;
3314     DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3315                                             /*Canonical=*/true);
3316     if (AEId == DAEId) {
3317       AllocatorKindRes = AllocatorKind;
3318       break;
3319     }
3320   }
3321   return AllocatorKindRes;
3322 }
3323 
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3324 static bool checkPreviousOMPAllocateAttribute(
3325     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3326     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3327   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3328     return false;
3329   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3330   Expr *PrevAllocator = A->getAllocator();
3331   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3332       getAllocatorKind(S, Stack, PrevAllocator);
3333   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3334   if (AllocatorsMatch &&
3335       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3336       Allocator && PrevAllocator) {
3337     const Expr *AE = Allocator->IgnoreParenImpCasts();
3338     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3339     llvm::FoldingSetNodeID AEId, PAEId;
3340     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3341     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3342     AllocatorsMatch = AEId == PAEId;
3343   }
3344   if (!AllocatorsMatch) {
3345     SmallString<256> AllocatorBuffer;
3346     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3347     if (Allocator)
3348       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3349     SmallString<256> PrevAllocatorBuffer;
3350     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3351     if (PrevAllocator)
3352       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3353                                  S.getPrintingPolicy());
3354 
3355     SourceLocation AllocatorLoc =
3356         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3357     SourceRange AllocatorRange =
3358         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3359     SourceLocation PrevAllocatorLoc =
3360         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3361     SourceRange PrevAllocatorRange =
3362         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3363     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3364         << (Allocator ? 1 : 0) << AllocatorStream.str()
3365         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3366         << AllocatorRange;
3367     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3368         << PrevAllocatorRange;
3369     return true;
3370   }
3371   return false;
3372 }
3373 
3374 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,Expr * Alignment,SourceRange SR)3375 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3376                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3377                           Expr *Allocator, Expr *Alignment, SourceRange SR) {
3378   if (VD->hasAttr<OMPAllocateDeclAttr>())
3379     return;
3380   if (Alignment &&
3381       (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3382        Alignment->isInstantiationDependent() ||
3383        Alignment->containsUnexpandedParameterPack()))
3384     // Apply later when we have a usable value.
3385     return;
3386   if (Allocator &&
3387       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3388        Allocator->isInstantiationDependent() ||
3389        Allocator->containsUnexpandedParameterPack()))
3390     return;
3391   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3392                                                 Allocator, Alignment, SR);
3393   VD->addAttr(A);
3394   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3395     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3396 }
3397 
3398 Sema::DeclGroupPtrTy
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3399 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3400                                    ArrayRef<OMPClause *> Clauses,
3401                                    DeclContext *Owner) {
3402   assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3403   Expr *Alignment = nullptr;
3404   Expr *Allocator = nullptr;
3405   if (Clauses.empty()) {
3406     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3407     // allocate directives that appear in a target region must specify an
3408     // allocator clause unless a requires directive with the dynamic_allocators
3409     // clause is present in the same compilation unit.
3410     if (LangOpts.OpenMPIsTargetDevice &&
3411         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3412       targetDiag(Loc, diag::err_expected_allocator_clause);
3413   } else {
3414     for (const OMPClause *C : Clauses)
3415       if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3416         Allocator = AC->getAllocator();
3417       else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3418         Alignment = AC->getAlignment();
3419       else
3420         llvm_unreachable("Unexpected clause on allocate directive");
3421   }
3422   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3423       getAllocatorKind(*this, DSAStack, Allocator);
3424   SmallVector<Expr *, 8> Vars;
3425   for (Expr *RefExpr : VarList) {
3426     auto *DE = cast<DeclRefExpr>(RefExpr);
3427     auto *VD = cast<VarDecl>(DE->getDecl());
3428 
3429     // Check if this is a TLS variable or global register.
3430     if (VD->getTLSKind() != VarDecl::TLS_None ||
3431         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3432         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3433          !VD->isLocalVarDecl()))
3434       continue;
3435 
3436     // If the used several times in the allocate directive, the same allocator
3437     // must be used.
3438     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3439                                           AllocatorKind, Allocator))
3440       continue;
3441 
3442     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3443     // If a list item has a static storage type, the allocator expression in the
3444     // allocator clause must be a constant expression that evaluates to one of
3445     // the predefined memory allocator values.
3446     if (Allocator && VD->hasGlobalStorage()) {
3447       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3448         Diag(Allocator->getExprLoc(),
3449              diag::err_omp_expected_predefined_allocator)
3450             << Allocator->getSourceRange();
3451         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3452                       VarDecl::DeclarationOnly;
3453         Diag(VD->getLocation(),
3454              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3455             << VD;
3456         continue;
3457       }
3458     }
3459 
3460     Vars.push_back(RefExpr);
3461     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3462                               DE->getSourceRange());
3463   }
3464   if (Vars.empty())
3465     return nullptr;
3466   if (!Owner)
3467     Owner = getCurLexicalContext();
3468   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3469   D->setAccess(AS_public);
3470   Owner->addDecl(D);
3471   return DeclGroupPtrTy::make(DeclGroupRef(D));
3472 }
3473 
3474 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3475 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3476                                    ArrayRef<OMPClause *> ClauseList) {
3477   OMPRequiresDecl *D = nullptr;
3478   if (!CurContext->isFileContext()) {
3479     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3480   } else {
3481     D = CheckOMPRequiresDecl(Loc, ClauseList);
3482     if (D) {
3483       CurContext->addDecl(D);
3484       DSAStack->addRequiresDecl(D);
3485     }
3486   }
3487   return DeclGroupPtrTy::make(DeclGroupRef(D));
3488 }
3489 
ActOnOpenMPAssumesDirective(SourceLocation Loc,OpenMPDirectiveKind DKind,ArrayRef<std::string> Assumptions,bool SkippedClauses)3490 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3491                                        OpenMPDirectiveKind DKind,
3492                                        ArrayRef<std::string> Assumptions,
3493                                        bool SkippedClauses) {
3494   if (!SkippedClauses && Assumptions.empty())
3495     Diag(Loc, diag::err_omp_no_clause_for_directive)
3496         << llvm::omp::getAllAssumeClauseOptions()
3497         << llvm::omp::getOpenMPDirectiveName(DKind);
3498 
3499   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3500   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3501     OMPAssumeScoped.push_back(AA);
3502     return;
3503   }
3504 
3505   // Global assumes without assumption clauses are ignored.
3506   if (Assumptions.empty())
3507     return;
3508 
3509   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3510          "Unexpected omp assumption directive!");
3511   OMPAssumeGlobal.push_back(AA);
3512 
3513   // The OMPAssumeGlobal scope above will take care of new declarations but
3514   // we also want to apply the assumption to existing ones, e.g., to
3515   // declarations in included headers. To this end, we traverse all existing
3516   // declaration contexts and annotate function declarations here.
3517   SmallVector<DeclContext *, 8> DeclContexts;
3518   auto *Ctx = CurContext;
3519   while (Ctx->getLexicalParent())
3520     Ctx = Ctx->getLexicalParent();
3521   DeclContexts.push_back(Ctx);
3522   while (!DeclContexts.empty()) {
3523     DeclContext *DC = DeclContexts.pop_back_val();
3524     for (auto *SubDC : DC->decls()) {
3525       if (SubDC->isInvalidDecl())
3526         continue;
3527       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3528         DeclContexts.push_back(CTD->getTemplatedDecl());
3529         llvm::append_range(DeclContexts, CTD->specializations());
3530         continue;
3531       }
3532       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3533         DeclContexts.push_back(DC);
3534       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3535         F->addAttr(AA);
3536         continue;
3537       }
3538     }
3539   }
3540 }
3541 
ActOnOpenMPEndAssumesDirective()3542 void Sema::ActOnOpenMPEndAssumesDirective() {
3543   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3544   OMPAssumeScoped.pop_back();
3545 }
3546 
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3547 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3548                                             ArrayRef<OMPClause *> ClauseList) {
3549   /// For target specific clauses, the requires directive cannot be
3550   /// specified after the handling of any of the target regions in the
3551   /// current compilation unit.
3552   ArrayRef<SourceLocation> TargetLocations =
3553       DSAStack->getEncounteredTargetLocs();
3554   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3555   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3556     for (const OMPClause *CNew : ClauseList) {
3557       // Check if any of the requires clauses affect target regions.
3558       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3559           isa<OMPUnifiedAddressClause>(CNew) ||
3560           isa<OMPReverseOffloadClause>(CNew) ||
3561           isa<OMPDynamicAllocatorsClause>(CNew)) {
3562         Diag(Loc, diag::err_omp_directive_before_requires)
3563             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3564         for (SourceLocation TargetLoc : TargetLocations) {
3565           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3566               << "target";
3567         }
3568       } else if (!AtomicLoc.isInvalid() &&
3569                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3570         Diag(Loc, diag::err_omp_directive_before_requires)
3571             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3572         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3573             << "atomic";
3574       }
3575     }
3576   }
3577 
3578   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3579     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3580                                    ClauseList);
3581   return nullptr;
3582 }
3583 
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3584 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3585                               const ValueDecl *D,
3586                               const DSAStackTy::DSAVarData &DVar,
3587                               bool IsLoopIterVar) {
3588   if (DVar.RefExpr) {
3589     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3590         << getOpenMPClauseName(DVar.CKind);
3591     return;
3592   }
3593   enum {
3594     PDSA_StaticMemberShared,
3595     PDSA_StaticLocalVarShared,
3596     PDSA_LoopIterVarPrivate,
3597     PDSA_LoopIterVarLinear,
3598     PDSA_LoopIterVarLastprivate,
3599     PDSA_ConstVarShared,
3600     PDSA_GlobalVarShared,
3601     PDSA_TaskVarFirstprivate,
3602     PDSA_LocalVarPrivate,
3603     PDSA_Implicit
3604   } Reason = PDSA_Implicit;
3605   bool ReportHint = false;
3606   auto ReportLoc = D->getLocation();
3607   auto *VD = dyn_cast<VarDecl>(D);
3608   if (IsLoopIterVar) {
3609     if (DVar.CKind == OMPC_private)
3610       Reason = PDSA_LoopIterVarPrivate;
3611     else if (DVar.CKind == OMPC_lastprivate)
3612       Reason = PDSA_LoopIterVarLastprivate;
3613     else
3614       Reason = PDSA_LoopIterVarLinear;
3615   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3616              DVar.CKind == OMPC_firstprivate) {
3617     Reason = PDSA_TaskVarFirstprivate;
3618     ReportLoc = DVar.ImplicitDSALoc;
3619   } else if (VD && VD->isStaticLocal())
3620     Reason = PDSA_StaticLocalVarShared;
3621   else if (VD && VD->isStaticDataMember())
3622     Reason = PDSA_StaticMemberShared;
3623   else if (VD && VD->isFileVarDecl())
3624     Reason = PDSA_GlobalVarShared;
3625   else if (D->getType().isConstant(SemaRef.getASTContext()))
3626     Reason = PDSA_ConstVarShared;
3627   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3628     ReportHint = true;
3629     Reason = PDSA_LocalVarPrivate;
3630   }
3631   if (Reason != PDSA_Implicit) {
3632     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3633         << Reason << ReportHint
3634         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3635   } else if (DVar.ImplicitDSALoc.isValid()) {
3636     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3637         << getOpenMPClauseName(DVar.CKind);
3638   }
3639 }
3640 
3641 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3642 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3643                              bool IsAggregateOrDeclareTarget) {
3644   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3645   switch (M) {
3646   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3647     Kind = OMPC_MAP_alloc;
3648     break;
3649   case OMPC_DEFAULTMAP_MODIFIER_to:
3650     Kind = OMPC_MAP_to;
3651     break;
3652   case OMPC_DEFAULTMAP_MODIFIER_from:
3653     Kind = OMPC_MAP_from;
3654     break;
3655   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3656     Kind = OMPC_MAP_tofrom;
3657     break;
3658   case OMPC_DEFAULTMAP_MODIFIER_present:
3659     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3660     // If implicit-behavior is present, each variable referenced in the
3661     // construct in the category specified by variable-category is treated as if
3662     // it had been listed in a map clause with the map-type of alloc and
3663     // map-type-modifier of present.
3664     Kind = OMPC_MAP_alloc;
3665     break;
3666   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3667   case OMPC_DEFAULTMAP_MODIFIER_last:
3668     llvm_unreachable("Unexpected defaultmap implicit behavior");
3669   case OMPC_DEFAULTMAP_MODIFIER_none:
3670   case OMPC_DEFAULTMAP_MODIFIER_default:
3671   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3672     // IsAggregateOrDeclareTarget could be true if:
3673     // 1. the implicit behavior for aggregate is tofrom
3674     // 2. it's a declare target link
3675     if (IsAggregateOrDeclareTarget) {
3676       Kind = OMPC_MAP_tofrom;
3677       break;
3678     }
3679     llvm_unreachable("Unexpected defaultmap implicit behavior");
3680   }
3681   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3682   return Kind;
3683 }
3684 
3685 namespace {
3686 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3687   DSAStackTy *Stack;
3688   Sema &SemaRef;
3689   bool ErrorFound = false;
3690   bool TryCaptureCXXThisMembers = false;
3691   CapturedStmt *CS = nullptr;
3692   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
3693   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3694   llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3695   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3696   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3697       ImplicitMapModifier[DefaultmapKindNum];
3698   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3699   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3700 
VisitSubCaptures(OMPExecutableDirective * S)3701   void VisitSubCaptures(OMPExecutableDirective *S) {
3702     // Check implicitly captured variables.
3703     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3704       return;
3705     if (S->getDirectiveKind() == OMPD_atomic ||
3706         S->getDirectiveKind() == OMPD_critical ||
3707         S->getDirectiveKind() == OMPD_section ||
3708         S->getDirectiveKind() == OMPD_master ||
3709         S->getDirectiveKind() == OMPD_masked ||
3710         S->getDirectiveKind() == OMPD_scope ||
3711         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3712       Visit(S->getAssociatedStmt());
3713       return;
3714     }
3715     visitSubCaptures(S->getInnermostCapturedStmt());
3716     // Try to capture inner this->member references to generate correct mappings
3717     // and diagnostics.
3718     if (TryCaptureCXXThisMembers ||
3719         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3720          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3721                       [](const CapturedStmt::Capture &C) {
3722                         return C.capturesThis();
3723                       }))) {
3724       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3725       TryCaptureCXXThisMembers = true;
3726       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3727       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3728     }
3729     // In tasks firstprivates are not captured anymore, need to analyze them
3730     // explicitly.
3731     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3732         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3733       for (OMPClause *C : S->clauses())
3734         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3735           for (Expr *Ref : FC->varlists())
3736             Visit(Ref);
3737         }
3738     }
3739   }
3740 
3741 public:
VisitDeclRefExpr(DeclRefExpr * E)3742   void VisitDeclRefExpr(DeclRefExpr *E) {
3743     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3744         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3745         E->isInstantiationDependent())
3746       return;
3747     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3748       // Check the datasharing rules for the expressions in the clauses.
3749       if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3750                   !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3751                   !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3752         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3753           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3754             Visit(CED->getInit());
3755             return;
3756           }
3757       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3758         // Do not analyze internal variables and do not enclose them into
3759         // implicit clauses.
3760         if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3761           return;
3762       VD = VD->getCanonicalDecl();
3763       // Skip internally declared variables.
3764       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3765           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3766           !Stack->isImplicitTaskFirstprivate(VD))
3767         return;
3768       // Skip allocators in uses_allocators clauses.
3769       if (Stack->isUsesAllocatorsDecl(VD))
3770         return;
3771 
3772       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3773       // Check if the variable has explicit DSA set and stop analysis if it so.
3774       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3775         return;
3776 
3777       // Skip internally declared static variables.
3778       std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3779           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3780       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3781           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3782            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3783           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3784           !Stack->isImplicitTaskFirstprivate(VD))
3785         return;
3786 
3787       SourceLocation ELoc = E->getExprLoc();
3788       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3789       // The default(none) clause requires that each variable that is referenced
3790       // in the construct, and does not have a predetermined data-sharing
3791       // attribute, must have its data-sharing attribute explicitly determined
3792       // by being listed in a data-sharing attribute clause.
3793       if (DVar.CKind == OMPC_unknown &&
3794           (Stack->getDefaultDSA() == DSA_none ||
3795            Stack->getDefaultDSA() == DSA_private ||
3796            Stack->getDefaultDSA() == DSA_firstprivate) &&
3797           isImplicitOrExplicitTaskingRegion(DKind) &&
3798           VarsWithInheritedDSA.count(VD) == 0) {
3799         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3800         if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3801                               Stack->getDefaultDSA() == DSA_private)) {
3802           DSAStackTy::DSAVarData DVar =
3803               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3804           InheritedDSA = DVar.CKind == OMPC_unknown;
3805         }
3806         if (InheritedDSA)
3807           VarsWithInheritedDSA[VD] = E;
3808         if (Stack->getDefaultDSA() == DSA_none)
3809           return;
3810       }
3811 
3812       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3813       // If implicit-behavior is none, each variable referenced in the
3814       // construct that does not have a predetermined data-sharing attribute
3815       // and does not appear in a to or link clause on a declare target
3816       // directive must be listed in a data-mapping attribute clause, a
3817       // data-sharing attribute clause (including a data-sharing attribute
3818       // clause on a combined construct where target. is one of the
3819       // constituent constructs), or an is_device_ptr clause.
3820       OpenMPDefaultmapClauseKind ClauseKind =
3821           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3822       if (SemaRef.getLangOpts().OpenMP >= 50) {
3823         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3824                               OMPC_DEFAULTMAP_MODIFIER_none;
3825         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3826             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3827           // Only check for data-mapping attribute and is_device_ptr here
3828           // since we have already make sure that the declaration does not
3829           // have a data-sharing attribute above
3830           if (!Stack->checkMappableExprComponentListsForDecl(
3831                   VD, /*CurrentRegionOnly=*/true,
3832                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3833                            MapExprComponents,
3834                        OpenMPClauseKind) {
3835                     auto MI = MapExprComponents.rbegin();
3836                     auto ME = MapExprComponents.rend();
3837                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3838                   })) {
3839             VarsWithInheritedDSA[VD] = E;
3840             return;
3841           }
3842         }
3843       }
3844       if (SemaRef.getLangOpts().OpenMP > 50) {
3845         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3846                                  OMPC_DEFAULTMAP_MODIFIER_present;
3847         if (IsModifierPresent) {
3848           if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3849                                   OMPC_MAP_MODIFIER_present)) {
3850             ImplicitMapModifier[ClauseKind].push_back(
3851                 OMPC_MAP_MODIFIER_present);
3852           }
3853         }
3854       }
3855 
3856       if (isOpenMPTargetExecutionDirective(DKind) &&
3857           !Stack->isLoopControlVariable(VD).first) {
3858         if (!Stack->checkMappableExprComponentListsForDecl(
3859                 VD, /*CurrentRegionOnly=*/true,
3860                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3861                            StackComponents,
3862                        OpenMPClauseKind) {
3863                   if (SemaRef.LangOpts.OpenMP >= 50)
3864                     return !StackComponents.empty();
3865                   // Variable is used if it has been marked as an array, array
3866                   // section, array shaping or the variable iself.
3867                   return StackComponents.size() == 1 ||
3868                          llvm::all_of(
3869                              llvm::drop_begin(llvm::reverse(StackComponents)),
3870                              [](const OMPClauseMappableExprCommon::
3871                                     MappableComponent &MC) {
3872                                return MC.getAssociatedDeclaration() ==
3873                                           nullptr &&
3874                                       (isa<OMPArraySectionExpr>(
3875                                            MC.getAssociatedExpression()) ||
3876                                        isa<OMPArrayShapingExpr>(
3877                                            MC.getAssociatedExpression()) ||
3878                                        isa<ArraySubscriptExpr>(
3879                                            MC.getAssociatedExpression()));
3880                              });
3881                 })) {
3882           bool IsFirstprivate = false;
3883           // By default lambdas are captured as firstprivates.
3884           if (const auto *RD =
3885                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3886             IsFirstprivate = RD->isLambda();
3887           IsFirstprivate =
3888               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3889           if (IsFirstprivate) {
3890             ImplicitFirstprivate.emplace_back(E);
3891           } else {
3892             OpenMPDefaultmapClauseModifier M =
3893                 Stack->getDefaultmapModifier(ClauseKind);
3894             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3895                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3896             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3897           }
3898           return;
3899         }
3900       }
3901 
3902       // OpenMP [2.9.3.6, Restrictions, p.2]
3903       //  A list item that appears in a reduction clause of the innermost
3904       //  enclosing worksharing or parallel construct may not be accessed in an
3905       //  explicit task.
3906       DVar = Stack->hasInnermostDSA(
3907           VD,
3908           [](OpenMPClauseKind C, bool AppliedToPointee) {
3909             return C == OMPC_reduction && !AppliedToPointee;
3910           },
3911           [](OpenMPDirectiveKind K) {
3912             return isOpenMPParallelDirective(K) ||
3913                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3914           },
3915           /*FromParent=*/true);
3916       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3917         ErrorFound = true;
3918         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3919         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3920         return;
3921       }
3922 
3923       // Define implicit data-sharing attributes for task.
3924       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3925       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3926            (((Stack->getDefaultDSA() == DSA_firstprivate &&
3927               DVar.CKind == OMPC_firstprivate) ||
3928              (Stack->getDefaultDSA() == DSA_private &&
3929               DVar.CKind == OMPC_private)) &&
3930             !DVar.RefExpr)) &&
3931           !Stack->isLoopControlVariable(VD).first) {
3932         if (Stack->getDefaultDSA() == DSA_private)
3933           ImplicitPrivate.push_back(E);
3934         else
3935           ImplicitFirstprivate.push_back(E);
3936         return;
3937       }
3938 
3939       // Store implicitly used globals with declare target link for parent
3940       // target.
3941       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3942           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3943         Stack->addToParentTargetRegionLinkGlobals(E);
3944         return;
3945       }
3946     }
3947   }
VisitMemberExpr(MemberExpr * E)3948   void VisitMemberExpr(MemberExpr *E) {
3949     if (E->isTypeDependent() || E->isValueDependent() ||
3950         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3951       return;
3952     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3953     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3954     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3955       if (!FD)
3956         return;
3957       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3958       // Check if the variable has explicit DSA set and stop analysis if it
3959       // so.
3960       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3961         return;
3962 
3963       if (isOpenMPTargetExecutionDirective(DKind) &&
3964           !Stack->isLoopControlVariable(FD).first &&
3965           !Stack->checkMappableExprComponentListsForDecl(
3966               FD, /*CurrentRegionOnly=*/true,
3967               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3968                      StackComponents,
3969                  OpenMPClauseKind) {
3970                 return isa<CXXThisExpr>(
3971                     cast<MemberExpr>(
3972                         StackComponents.back().getAssociatedExpression())
3973                         ->getBase()
3974                         ->IgnoreParens());
3975               })) {
3976         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3977         //  A bit-field cannot appear in a map clause.
3978         //
3979         if (FD->isBitField())
3980           return;
3981 
3982         // Check to see if the member expression is referencing a class that
3983         // has already been explicitly mapped
3984         if (Stack->isClassPreviouslyMapped(TE->getType()))
3985           return;
3986 
3987         OpenMPDefaultmapClauseModifier Modifier =
3988             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3989         OpenMPDefaultmapClauseKind ClauseKind =
3990             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3991         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3992             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3993         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3994         return;
3995       }
3996 
3997       SourceLocation ELoc = E->getExprLoc();
3998       // OpenMP [2.9.3.6, Restrictions, p.2]
3999       //  A list item that appears in a reduction clause of the innermost
4000       //  enclosing worksharing or parallel construct may not be accessed in
4001       //  an  explicit task.
4002       DVar = Stack->hasInnermostDSA(
4003           FD,
4004           [](OpenMPClauseKind C, bool AppliedToPointee) {
4005             return C == OMPC_reduction && !AppliedToPointee;
4006           },
4007           [](OpenMPDirectiveKind K) {
4008             return isOpenMPParallelDirective(K) ||
4009                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
4010           },
4011           /*FromParent=*/true);
4012       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
4013         ErrorFound = true;
4014         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
4015         reportOriginalDsa(SemaRef, Stack, FD, DVar);
4016         return;
4017       }
4018 
4019       // Define implicit data-sharing attributes for task.
4020       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
4021       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
4022           !Stack->isLoopControlVariable(FD).first) {
4023         // Check if there is a captured expression for the current field in the
4024         // region. Do not mark it as firstprivate unless there is no captured
4025         // expression.
4026         // TODO: try to make it firstprivate.
4027         if (DVar.CKind != OMPC_unknown)
4028           ImplicitFirstprivate.push_back(E);
4029       }
4030       return;
4031     }
4032     if (isOpenMPTargetExecutionDirective(DKind)) {
4033       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
4034       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4035                                         Stack->getCurrentDirective(),
4036                                         /*NoDiagnose=*/true))
4037         return;
4038       const auto *VD = cast<ValueDecl>(
4039           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4040       if (!Stack->checkMappableExprComponentListsForDecl(
4041               VD, /*CurrentRegionOnly=*/true,
4042               [&CurComponents](
4043                   OMPClauseMappableExprCommon::MappableExprComponentListRef
4044                       StackComponents,
4045                   OpenMPClauseKind) {
4046                 auto CCI = CurComponents.rbegin();
4047                 auto CCE = CurComponents.rend();
4048                 for (const auto &SC : llvm::reverse(StackComponents)) {
4049                   // Do both expressions have the same kind?
4050                   if (CCI->getAssociatedExpression()->getStmtClass() !=
4051                       SC.getAssociatedExpression()->getStmtClass())
4052                     if (!((isa<OMPArraySectionExpr>(
4053                                SC.getAssociatedExpression()) ||
4054                            isa<OMPArrayShapingExpr>(
4055                                SC.getAssociatedExpression())) &&
4056                           isa<ArraySubscriptExpr>(
4057                               CCI->getAssociatedExpression())))
4058                       return false;
4059 
4060                   const Decl *CCD = CCI->getAssociatedDeclaration();
4061                   const Decl *SCD = SC.getAssociatedDeclaration();
4062                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4063                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4064                   if (SCD != CCD)
4065                     return false;
4066                   std::advance(CCI, 1);
4067                   if (CCI == CCE)
4068                     break;
4069                 }
4070                 return true;
4071               })) {
4072         Visit(E->getBase());
4073       }
4074     } else if (!TryCaptureCXXThisMembers) {
4075       Visit(E->getBase());
4076     }
4077   }
VisitOMPExecutableDirective(OMPExecutableDirective * S)4078   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4079     for (OMPClause *C : S->clauses()) {
4080       // Skip analysis of arguments of private clauses for task|target
4081       // directives.
4082       if (isa_and_nonnull<OMPPrivateClause>(C))
4083         continue;
4084       // Skip analysis of arguments of implicitly defined firstprivate clause
4085       // for task|target directives.
4086       // Skip analysis of arguments of implicitly defined map clause for target
4087       // directives.
4088       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4089                  C->isImplicit() &&
4090                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4091         for (Stmt *CC : C->children()) {
4092           if (CC)
4093             Visit(CC);
4094         }
4095       }
4096     }
4097     // Check implicitly captured variables.
4098     VisitSubCaptures(S);
4099   }
4100 
VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective * S)4101   void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4102     // Loop transformation directives do not introduce data sharing
4103     VisitStmt(S);
4104   }
4105 
VisitCallExpr(CallExpr * S)4106   void VisitCallExpr(CallExpr *S) {
4107     for (Stmt *C : S->arguments()) {
4108       if (C) {
4109         // Check implicitly captured variables in the task-based directives to
4110         // check if they must be firstprivatized.
4111         Visit(C);
4112       }
4113     }
4114     if (Expr *Callee = S->getCallee()) {
4115       auto *CI = Callee->IgnoreParenImpCasts();
4116       if (auto *CE = dyn_cast<MemberExpr>(CI))
4117         Visit(CE->getBase());
4118       else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4119         Visit(CE);
4120     }
4121   }
VisitStmt(Stmt * S)4122   void VisitStmt(Stmt *S) {
4123     for (Stmt *C : S->children()) {
4124       if (C) {
4125         // Check implicitly captured variables in the task-based directives to
4126         // check if they must be firstprivatized.
4127         Visit(C);
4128       }
4129     }
4130   }
4131 
visitSubCaptures(CapturedStmt * S)4132   void visitSubCaptures(CapturedStmt *S) {
4133     for (const CapturedStmt::Capture &Cap : S->captures()) {
4134       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4135         continue;
4136       VarDecl *VD = Cap.getCapturedVar();
4137       // Do not try to map the variable if it or its sub-component was mapped
4138       // already.
4139       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4140           Stack->checkMappableExprComponentListsForDecl(
4141               VD, /*CurrentRegionOnly=*/true,
4142               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4143                  OpenMPClauseKind) { return true; }))
4144         continue;
4145       DeclRefExpr *DRE = buildDeclRefExpr(
4146           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4147           Cap.getLocation(), /*RefersToCapture=*/true);
4148       Visit(DRE);
4149     }
4150   }
isErrorFound() const4151   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const4152   ArrayRef<Expr *> getImplicitFirstprivate() const {
4153     return ImplicitFirstprivate;
4154   }
getImplicitPrivate() const4155   ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const4156   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4157                                   OpenMPMapClauseKind MK) const {
4158     return ImplicitMap[DK][MK];
4159   }
4160   ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const4161   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4162     return ImplicitMapModifier[Kind];
4163   }
getVarsWithInheritedDSA() const4164   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4165     return VarsWithInheritedDSA;
4166   }
4167 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)4168   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4169       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4170     // Process declare target link variables for the target directives.
4171     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4172       for (DeclRefExpr *E : Stack->getLinkGlobals())
4173         Visit(E);
4174     }
4175   }
4176 };
4177 } // namespace
4178 
handleDeclareVariantConstructTrait(DSAStackTy * Stack,OpenMPDirectiveKind DKind,bool ScopeEntry)4179 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4180                                                OpenMPDirectiveKind DKind,
4181                                                bool ScopeEntry) {
4182   SmallVector<llvm::omp::TraitProperty, 8> Traits;
4183   if (isOpenMPTargetExecutionDirective(DKind))
4184     Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4185   if (isOpenMPTeamsDirective(DKind))
4186     Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4187   if (isOpenMPParallelDirective(DKind))
4188     Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4189   if (isOpenMPWorksharingDirective(DKind))
4190     Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4191   if (isOpenMPSimdDirective(DKind))
4192     Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4193   Stack->handleConstructTrait(Traits, ScopeEntry);
4194 }
4195 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)4196 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4197   switch (DKind) {
4198   case OMPD_parallel:
4199   case OMPD_parallel_for:
4200   case OMPD_parallel_for_simd:
4201   case OMPD_parallel_sections:
4202   case OMPD_parallel_master:
4203   case OMPD_parallel_masked:
4204   case OMPD_parallel_loop:
4205   case OMPD_teams:
4206   case OMPD_teams_distribute:
4207   case OMPD_teams_distribute_simd: {
4208     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209     QualType KmpInt32PtrTy =
4210         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4211     Sema::CapturedParamNameType Params[] = {
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     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4217                              Params);
4218     break;
4219   }
4220   case OMPD_target_teams:
4221   case OMPD_target_parallel:
4222   case OMPD_target_parallel_for:
4223   case OMPD_target_parallel_for_simd:
4224   case OMPD_target_parallel_loop:
4225   case OMPD_target_teams_distribute:
4226   case OMPD_target_teams_distribute_simd: {
4227     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4228     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4229     QualType KmpInt32PtrTy =
4230         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4231     QualType Args[] = {VoidPtrTy};
4232     FunctionProtoType::ExtProtoInfo EPI;
4233     EPI.Variadic = true;
4234     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4235     Sema::CapturedParamNameType Params[] = {
4236         std::make_pair(".global_tid.", KmpInt32Ty),
4237         std::make_pair(".part_id.", KmpInt32PtrTy),
4238         std::make_pair(".privates.", VoidPtrTy),
4239         std::make_pair(
4240             ".copy_fn.",
4241             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4242         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4243         std::make_pair(StringRef(), QualType()) // __context with shared vars
4244     };
4245     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4246                              Params, /*OpenMPCaptureLevel=*/0);
4247     // Mark this captured region as inlined, because we don't use outlined
4248     // function directly.
4249     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4250         AlwaysInlineAttr::CreateImplicit(
4251             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4252     SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4253     if (getLangOpts().OpenMPIsTargetDevice)
4254       ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4255     ParamsTarget.push_back(
4256         std::make_pair(StringRef(), QualType())); // __context with shared vars;
4257     // Start a captured region for 'target' with no implicit parameters.
4258     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4259                              ParamsTarget,
4260                              /*OpenMPCaptureLevel=*/1);
4261     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4262         std::make_pair(".global_tid.", KmpInt32PtrTy),
4263         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4264         std::make_pair(StringRef(), QualType()) // __context with shared vars
4265     };
4266     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4267     // the same implicit parameters.
4268     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4269                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4270     break;
4271   }
4272   case OMPD_target:
4273   case OMPD_target_simd: {
4274     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4275     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4276     QualType KmpInt32PtrTy =
4277         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4278     QualType Args[] = {VoidPtrTy};
4279     FunctionProtoType::ExtProtoInfo EPI;
4280     EPI.Variadic = true;
4281     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4282     Sema::CapturedParamNameType Params[] = {
4283         std::make_pair(".global_tid.", KmpInt32Ty),
4284         std::make_pair(".part_id.", KmpInt32PtrTy),
4285         std::make_pair(".privates.", VoidPtrTy),
4286         std::make_pair(
4287             ".copy_fn.",
4288             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4289         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4290         std::make_pair(StringRef(), QualType()) // __context with shared vars
4291     };
4292     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4293                              Params, /*OpenMPCaptureLevel=*/0);
4294     // Mark this captured region as inlined, because we don't use outlined
4295     // function directly.
4296     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4297         AlwaysInlineAttr::CreateImplicit(
4298             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4299     SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4300     if (getLangOpts().OpenMPIsTargetDevice)
4301       ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4302     ParamsTarget.push_back(
4303         std::make_pair(StringRef(), QualType())); // __context with shared vars;
4304     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4305                              ParamsTarget,
4306                              /*OpenMPCaptureLevel=*/1);
4307     break;
4308   }
4309   case OMPD_atomic:
4310   case OMPD_critical:
4311   case OMPD_section:
4312   case OMPD_master:
4313   case OMPD_masked:
4314   case OMPD_tile:
4315   case OMPD_unroll:
4316     break;
4317   case OMPD_loop:
4318     // TODO: 'loop' may require additional parameters depending on the binding.
4319     // Treat similar to OMPD_simd/OMPD_for for now.
4320   case OMPD_simd:
4321   case OMPD_for:
4322   case OMPD_for_simd:
4323   case OMPD_sections:
4324   case OMPD_single:
4325   case OMPD_taskgroup:
4326   case OMPD_distribute:
4327   case OMPD_distribute_simd:
4328   case OMPD_ordered:
4329   case OMPD_scope:
4330   case OMPD_target_data:
4331   case OMPD_dispatch: {
4332     Sema::CapturedParamNameType Params[] = {
4333         std::make_pair(StringRef(), QualType()) // __context with shared vars
4334     };
4335     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4336                              Params);
4337     break;
4338   }
4339   case OMPD_task: {
4340     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4341     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4342     QualType KmpInt32PtrTy =
4343         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4344     QualType Args[] = {VoidPtrTy};
4345     FunctionProtoType::ExtProtoInfo EPI;
4346     EPI.Variadic = true;
4347     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4348     Sema::CapturedParamNameType Params[] = {
4349         std::make_pair(".global_tid.", KmpInt32Ty),
4350         std::make_pair(".part_id.", KmpInt32PtrTy),
4351         std::make_pair(".privates.", VoidPtrTy),
4352         std::make_pair(
4353             ".copy_fn.",
4354             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4355         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4356         std::make_pair(StringRef(), QualType()) // __context with shared vars
4357     };
4358     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4359                              Params);
4360     // Mark this captured region as inlined, because we don't use outlined
4361     // function directly.
4362     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4363         AlwaysInlineAttr::CreateImplicit(
4364             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4365     break;
4366   }
4367   case OMPD_taskloop:
4368   case OMPD_taskloop_simd:
4369   case OMPD_master_taskloop:
4370   case OMPD_masked_taskloop:
4371   case OMPD_masked_taskloop_simd:
4372   case OMPD_master_taskloop_simd: {
4373     QualType KmpInt32Ty =
4374         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4375             .withConst();
4376     QualType KmpUInt64Ty =
4377         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4378             .withConst();
4379     QualType KmpInt64Ty =
4380         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4381             .withConst();
4382     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4383     QualType KmpInt32PtrTy =
4384         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4385     QualType Args[] = {VoidPtrTy};
4386     FunctionProtoType::ExtProtoInfo EPI;
4387     EPI.Variadic = true;
4388     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4389     Sema::CapturedParamNameType Params[] = {
4390         std::make_pair(".global_tid.", KmpInt32Ty),
4391         std::make_pair(".part_id.", KmpInt32PtrTy),
4392         std::make_pair(".privates.", VoidPtrTy),
4393         std::make_pair(
4394             ".copy_fn.",
4395             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4396         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4397         std::make_pair(".lb.", KmpUInt64Ty),
4398         std::make_pair(".ub.", KmpUInt64Ty),
4399         std::make_pair(".st.", KmpInt64Ty),
4400         std::make_pair(".liter.", KmpInt32Ty),
4401         std::make_pair(".reductions.", VoidPtrTy),
4402         std::make_pair(StringRef(), QualType()) // __context with shared vars
4403     };
4404     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4405                              Params);
4406     // Mark this captured region as inlined, because we don't use outlined
4407     // function directly.
4408     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4409         AlwaysInlineAttr::CreateImplicit(
4410             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4411     break;
4412   }
4413   case OMPD_parallel_masked_taskloop:
4414   case OMPD_parallel_masked_taskloop_simd:
4415   case OMPD_parallel_master_taskloop:
4416   case OMPD_parallel_master_taskloop_simd: {
4417     QualType KmpInt32Ty =
4418         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4419             .withConst();
4420     QualType KmpUInt64Ty =
4421         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4422             .withConst();
4423     QualType KmpInt64Ty =
4424         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4425             .withConst();
4426     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4427     QualType KmpInt32PtrTy =
4428         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4429     Sema::CapturedParamNameType ParamsParallel[] = {
4430         std::make_pair(".global_tid.", KmpInt32PtrTy),
4431         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4432         std::make_pair(StringRef(), QualType()) // __context with shared vars
4433     };
4434     // Start a captured region for 'parallel'.
4435     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4436                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4437     QualType Args[] = {VoidPtrTy};
4438     FunctionProtoType::ExtProtoInfo EPI;
4439     EPI.Variadic = true;
4440     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4441     Sema::CapturedParamNameType Params[] = {
4442         std::make_pair(".global_tid.", KmpInt32Ty),
4443         std::make_pair(".part_id.", KmpInt32PtrTy),
4444         std::make_pair(".privates.", VoidPtrTy),
4445         std::make_pair(
4446             ".copy_fn.",
4447             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4448         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4449         std::make_pair(".lb.", KmpUInt64Ty),
4450         std::make_pair(".ub.", KmpUInt64Ty),
4451         std::make_pair(".st.", KmpInt64Ty),
4452         std::make_pair(".liter.", KmpInt32Ty),
4453         std::make_pair(".reductions.", VoidPtrTy),
4454         std::make_pair(StringRef(), QualType()) // __context with shared vars
4455     };
4456     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4457                              Params, /*OpenMPCaptureLevel=*/1);
4458     // Mark this captured region as inlined, because we don't use outlined
4459     // function directly.
4460     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4461         AlwaysInlineAttr::CreateImplicit(
4462             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4463     break;
4464   }
4465   case OMPD_distribute_parallel_for_simd:
4466   case OMPD_distribute_parallel_for: {
4467     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4468     QualType KmpInt32PtrTy =
4469         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4470     Sema::CapturedParamNameType Params[] = {
4471         std::make_pair(".global_tid.", KmpInt32PtrTy),
4472         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4473         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4474         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4475         std::make_pair(StringRef(), QualType()) // __context with shared vars
4476     };
4477     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4478                              Params);
4479     break;
4480   }
4481   case OMPD_target_teams_loop:
4482   case OMPD_target_teams_distribute_parallel_for:
4483   case OMPD_target_teams_distribute_parallel_for_simd: {
4484     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4485     QualType KmpInt32PtrTy =
4486         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4487     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4488 
4489     QualType Args[] = {VoidPtrTy};
4490     FunctionProtoType::ExtProtoInfo EPI;
4491     EPI.Variadic = true;
4492     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4493     Sema::CapturedParamNameType Params[] = {
4494         std::make_pair(".global_tid.", KmpInt32Ty),
4495         std::make_pair(".part_id.", KmpInt32PtrTy),
4496         std::make_pair(".privates.", VoidPtrTy),
4497         std::make_pair(
4498             ".copy_fn.",
4499             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4500         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4501         std::make_pair(StringRef(), QualType()) // __context with shared vars
4502     };
4503     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4504                              Params, /*OpenMPCaptureLevel=*/0);
4505     // Mark this captured region as inlined, because we don't use outlined
4506     // function directly.
4507     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4508         AlwaysInlineAttr::CreateImplicit(
4509             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4510     SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4511     if (getLangOpts().OpenMPIsTargetDevice)
4512       ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4513     ParamsTarget.push_back(
4514         std::make_pair(StringRef(), QualType())); // __context with shared vars;
4515     // Start a captured region for 'target' with no implicit parameters.
4516     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4517                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4518 
4519     Sema::CapturedParamNameType ParamsTeams[] = {
4520         std::make_pair(".global_tid.", KmpInt32PtrTy),
4521         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4522         std::make_pair(StringRef(), QualType()) // __context with shared vars
4523     };
4524     // Start a captured region for 'target' with no implicit parameters.
4525     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4526                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4527 
4528     Sema::CapturedParamNameType ParamsParallel[] = {
4529         std::make_pair(".global_tid.", KmpInt32PtrTy),
4530         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4531         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4532         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4533         std::make_pair(StringRef(), QualType()) // __context with shared vars
4534     };
4535     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4536     // the same implicit parameters.
4537     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4538                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4539     break;
4540   }
4541 
4542   case OMPD_teams_loop:
4543   case OMPD_teams_distribute_parallel_for:
4544   case OMPD_teams_distribute_parallel_for_simd: {
4545     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4546     QualType KmpInt32PtrTy =
4547         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4548 
4549     Sema::CapturedParamNameType ParamsTeams[] = {
4550         std::make_pair(".global_tid.", KmpInt32PtrTy),
4551         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4552         std::make_pair(StringRef(), QualType()) // __context with shared vars
4553     };
4554     // Start a captured region for 'target' with no implicit parameters.
4555     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4556                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4557 
4558     Sema::CapturedParamNameType ParamsParallel[] = {
4559         std::make_pair(".global_tid.", KmpInt32PtrTy),
4560         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4561         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4562         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4563         std::make_pair(StringRef(), QualType()) // __context with shared vars
4564     };
4565     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4566     // the same implicit parameters.
4567     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4568                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4569     break;
4570   }
4571   case OMPD_target_update:
4572   case OMPD_target_enter_data:
4573   case OMPD_target_exit_data: {
4574     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4575     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4576     QualType KmpInt32PtrTy =
4577         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4578     QualType Args[] = {VoidPtrTy};
4579     FunctionProtoType::ExtProtoInfo EPI;
4580     EPI.Variadic = true;
4581     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4582     Sema::CapturedParamNameType Params[] = {
4583         std::make_pair(".global_tid.", KmpInt32Ty),
4584         std::make_pair(".part_id.", KmpInt32PtrTy),
4585         std::make_pair(".privates.", VoidPtrTy),
4586         std::make_pair(
4587             ".copy_fn.",
4588             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4589         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4590         std::make_pair(StringRef(), QualType()) // __context with shared vars
4591     };
4592     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4593                              Params);
4594     // Mark this captured region as inlined, because we don't use outlined
4595     // function directly.
4596     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4597         AlwaysInlineAttr::CreateImplicit(
4598             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4599     break;
4600   }
4601   case OMPD_threadprivate:
4602   case OMPD_allocate:
4603   case OMPD_taskyield:
4604   case OMPD_error:
4605   case OMPD_barrier:
4606   case OMPD_taskwait:
4607   case OMPD_cancellation_point:
4608   case OMPD_cancel:
4609   case OMPD_flush:
4610   case OMPD_depobj:
4611   case OMPD_scan:
4612   case OMPD_declare_reduction:
4613   case OMPD_declare_mapper:
4614   case OMPD_declare_simd:
4615   case OMPD_declare_target:
4616   case OMPD_end_declare_target:
4617   case OMPD_requires:
4618   case OMPD_declare_variant:
4619   case OMPD_begin_declare_variant:
4620   case OMPD_end_declare_variant:
4621   case OMPD_metadirective:
4622     llvm_unreachable("OpenMP Directive is not allowed");
4623   case OMPD_unknown:
4624   default:
4625     llvm_unreachable("Unknown OpenMP directive");
4626   }
4627   DSAStack->setContext(CurContext);
4628   handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4629 }
4630 
getNumberOfConstructScopes(unsigned Level) const4631 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4632   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4633 }
4634 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4635 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4636   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4637   getOpenMPCaptureRegions(CaptureRegions, DKind);
4638   return CaptureRegions.size();
4639 }
4640 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,DeclContext * CurContext,bool AsExpression)4641 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4642                                              Expr *CaptureExpr, bool WithInit,
4643                                              DeclContext *CurContext,
4644                                              bool AsExpression) {
4645   assert(CaptureExpr);
4646   ASTContext &C = S.getASTContext();
4647   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4648   QualType Ty = Init->getType();
4649   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4650     if (S.getLangOpts().CPlusPlus) {
4651       Ty = C.getLValueReferenceType(Ty);
4652     } else {
4653       Ty = C.getPointerType(Ty);
4654       ExprResult Res =
4655           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4656       if (!Res.isUsable())
4657         return nullptr;
4658       Init = Res.get();
4659     }
4660     WithInit = true;
4661   }
4662   auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4663                                           CaptureExpr->getBeginLoc());
4664   if (!WithInit)
4665     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4666   CurContext->addHiddenDecl(CED);
4667   Sema::TentativeAnalysisScope Trap(S);
4668   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4669   return CED;
4670 }
4671 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4672 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4673                                  bool WithInit) {
4674   OMPCapturedExprDecl *CD;
4675   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4676     CD = cast<OMPCapturedExprDecl>(VD);
4677   else
4678     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4679                           S.CurContext,
4680                           /*AsExpression=*/false);
4681   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4682                           CaptureExpr->getExprLoc());
4683 }
4684 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref,StringRef Name)4685 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4686                                StringRef Name) {
4687   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4688   if (!Ref) {
4689     OMPCapturedExprDecl *CD = buildCaptureDecl(
4690         S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4691         /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4692     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4693                            CaptureExpr->getExprLoc());
4694   }
4695   ExprResult Res = Ref;
4696   if (!S.getLangOpts().CPlusPlus &&
4697       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4698       Ref->getType()->isPointerType()) {
4699     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4700     if (!Res.isUsable())
4701       return ExprError();
4702   }
4703   return S.DefaultLvalueConversion(Res.get());
4704 }
4705 
4706 namespace {
4707 // OpenMP directives parsed in this section are represented as a
4708 // CapturedStatement with an associated statement.  If a syntax error
4709 // is detected during the parsing of the associated statement, the
4710 // compiler must abort processing and close the CapturedStatement.
4711 //
4712 // Combined directives such as 'target parallel' have more than one
4713 // nested CapturedStatements.  This RAII ensures that we unwind out
4714 // of all the nested CapturedStatements when an error is found.
4715 class CaptureRegionUnwinderRAII {
4716 private:
4717   Sema &S;
4718   bool &ErrorFound;
4719   OpenMPDirectiveKind DKind = OMPD_unknown;
4720 
4721 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4722   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4723                             OpenMPDirectiveKind DKind)
4724       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4725   ~CaptureRegionUnwinderRAII() {
4726     if (ErrorFound) {
4727       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4728       while (--ThisCaptureLevel >= 0)
4729         S.ActOnCapturedRegionError();
4730     }
4731   }
4732 };
4733 } // namespace
4734 
tryCaptureOpenMPLambdas(ValueDecl * V)4735 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4736   // Capture variables captured by reference in lambdas for target-based
4737   // directives.
4738   if (!CurContext->isDependentContext() &&
4739       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4740        isOpenMPTargetDataManagementDirective(
4741            DSAStack->getCurrentDirective()))) {
4742     QualType Type = V->getType();
4743     if (const auto *RD = Type.getCanonicalType()
4744                              .getNonReferenceType()
4745                              ->getAsCXXRecordDecl()) {
4746       bool SavedForceCaptureByReferenceInTargetExecutable =
4747           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4748       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4749           /*V=*/true);
4750       if (RD->isLambda()) {
4751         llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4752         FieldDecl *ThisCapture;
4753         RD->getCaptureFields(Captures, ThisCapture);
4754         for (const LambdaCapture &LC : RD->captures()) {
4755           if (LC.getCaptureKind() == LCK_ByRef) {
4756             VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4757             DeclContext *VDC = VD->getDeclContext();
4758             if (!VDC->Encloses(CurContext))
4759               continue;
4760             MarkVariableReferenced(LC.getLocation(), VD);
4761           } else if (LC.getCaptureKind() == LCK_This) {
4762             QualType ThisTy = getCurrentThisType();
4763             if (!ThisTy.isNull() &&
4764                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4765               CheckCXXThisCapture(LC.getLocation());
4766           }
4767         }
4768       }
4769       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4770           SavedForceCaptureByReferenceInTargetExecutable);
4771     }
4772   }
4773 }
4774 
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4775 static bool checkOrderedOrderSpecified(Sema &S,
4776                                        const ArrayRef<OMPClause *> Clauses) {
4777   const OMPOrderedClause *Ordered = nullptr;
4778   const OMPOrderClause *Order = nullptr;
4779 
4780   for (const OMPClause *Clause : Clauses) {
4781     if (Clause->getClauseKind() == OMPC_ordered)
4782       Ordered = cast<OMPOrderedClause>(Clause);
4783     else if (Clause->getClauseKind() == OMPC_order) {
4784       Order = cast<OMPOrderClause>(Clause);
4785       if (Order->getKind() != OMPC_ORDER_concurrent)
4786         Order = nullptr;
4787     }
4788     if (Ordered && Order)
4789       break;
4790   }
4791 
4792   if (Ordered && Order) {
4793     S.Diag(Order->getKindKwLoc(),
4794            diag::err_omp_simple_clause_incompatible_with_ordered)
4795         << getOpenMPClauseName(OMPC_order)
4796         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4797         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4798     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4799         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4800     return true;
4801   }
4802   return false;
4803 }
4804 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4805 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4806                                       ArrayRef<OMPClause *> Clauses) {
4807   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4808                                      /* ScopeEntry */ false);
4809   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4810       DSAStack->getCurrentDirective() == OMPD_critical ||
4811       DSAStack->getCurrentDirective() == OMPD_section ||
4812       DSAStack->getCurrentDirective() == OMPD_master ||
4813       DSAStack->getCurrentDirective() == OMPD_masked)
4814     return S;
4815 
4816   bool ErrorFound = false;
4817   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4818       *this, ErrorFound, DSAStack->getCurrentDirective());
4819   if (!S.isUsable()) {
4820     ErrorFound = true;
4821     return StmtError();
4822   }
4823 
4824   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4825   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4826   OMPOrderedClause *OC = nullptr;
4827   OMPScheduleClause *SC = nullptr;
4828   SmallVector<const OMPLinearClause *, 4> LCs;
4829   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4830   // This is required for proper codegen.
4831   for (OMPClause *Clause : Clauses) {
4832     if (!LangOpts.OpenMPSimd &&
4833         (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4834          DSAStack->getCurrentDirective() == OMPD_target) &&
4835         Clause->getClauseKind() == OMPC_in_reduction) {
4836       // Capture taskgroup task_reduction descriptors inside the tasking regions
4837       // with the corresponding in_reduction items.
4838       auto *IRC = cast<OMPInReductionClause>(Clause);
4839       for (Expr *E : IRC->taskgroup_descriptors())
4840         if (E)
4841           MarkDeclarationsReferencedInExpr(E);
4842     }
4843     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4844         Clause->getClauseKind() == OMPC_copyprivate ||
4845         (getLangOpts().OpenMPUseTLS &&
4846          getASTContext().getTargetInfo().isTLSSupported() &&
4847          Clause->getClauseKind() == OMPC_copyin)) {
4848       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4849       // Mark all variables in private list clauses as used in inner region.
4850       for (Stmt *VarRef : Clause->children()) {
4851         if (auto *E = cast_or_null<Expr>(VarRef)) {
4852           MarkDeclarationsReferencedInExpr(E);
4853         }
4854       }
4855       DSAStack->setForceVarCapturing(/*V=*/false);
4856     } else if (isOpenMPLoopTransformationDirective(
4857                    DSAStack->getCurrentDirective())) {
4858       assert(CaptureRegions.empty() &&
4859              "No captured regions in loop transformation directives.");
4860     } else if (CaptureRegions.size() > 1 ||
4861                CaptureRegions.back() != OMPD_unknown) {
4862       if (auto *C = OMPClauseWithPreInit::get(Clause))
4863         PICs.push_back(C);
4864       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4865         if (Expr *E = C->getPostUpdateExpr())
4866           MarkDeclarationsReferencedInExpr(E);
4867       }
4868     }
4869     if (Clause->getClauseKind() == OMPC_schedule)
4870       SC = cast<OMPScheduleClause>(Clause);
4871     else if (Clause->getClauseKind() == OMPC_ordered)
4872       OC = cast<OMPOrderedClause>(Clause);
4873     else if (Clause->getClauseKind() == OMPC_linear)
4874       LCs.push_back(cast<OMPLinearClause>(Clause));
4875   }
4876   // Capture allocator expressions if used.
4877   for (Expr *E : DSAStack->getInnerAllocators())
4878     MarkDeclarationsReferencedInExpr(E);
4879   // OpenMP, 2.7.1 Loop Construct, Restrictions
4880   // The nonmonotonic modifier cannot be specified if an ordered clause is
4881   // specified.
4882   if (SC &&
4883       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4884        SC->getSecondScheduleModifier() ==
4885            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4886       OC) {
4887     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4888              ? SC->getFirstScheduleModifierLoc()
4889              : SC->getSecondScheduleModifierLoc(),
4890          diag::err_omp_simple_clause_incompatible_with_ordered)
4891         << getOpenMPClauseName(OMPC_schedule)
4892         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4893                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4894         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4895     ErrorFound = true;
4896   }
4897   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4898   // If an order(concurrent) clause is present, an ordered clause may not appear
4899   // on the same directive.
4900   if (checkOrderedOrderSpecified(*this, Clauses))
4901     ErrorFound = true;
4902   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4903     for (const OMPLinearClause *C : LCs) {
4904       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4905           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4906     }
4907     ErrorFound = true;
4908   }
4909   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4910       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4911       OC->getNumForLoops()) {
4912     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4913         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4914     ErrorFound = true;
4915   }
4916   if (ErrorFound) {
4917     return StmtError();
4918   }
4919   StmtResult SR = S;
4920   unsigned CompletedRegions = 0;
4921   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4922     // Mark all variables in private list clauses as used in inner region.
4923     // Required for proper codegen of combined directives.
4924     // TODO: add processing for other clauses.
4925     if (ThisCaptureRegion != OMPD_unknown) {
4926       for (const clang::OMPClauseWithPreInit *C : PICs) {
4927         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4928         // Find the particular capture region for the clause if the
4929         // directive is a combined one with multiple capture regions.
4930         // If the directive is not a combined one, the capture region
4931         // associated with the clause is OMPD_unknown and is generated
4932         // only once.
4933         if (CaptureRegion == ThisCaptureRegion ||
4934             CaptureRegion == OMPD_unknown) {
4935           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4936             for (Decl *D : DS->decls())
4937               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4938           }
4939         }
4940       }
4941     }
4942     if (ThisCaptureRegion == OMPD_target) {
4943       // Capture allocator traits in the target region. They are used implicitly
4944       // and, thus, are not captured by default.
4945       for (OMPClause *C : Clauses) {
4946         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4947           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4948                ++I) {
4949             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4950             if (Expr *E = D.AllocatorTraits)
4951               MarkDeclarationsReferencedInExpr(E);
4952           }
4953           continue;
4954         }
4955       }
4956     }
4957     if (ThisCaptureRegion == OMPD_parallel) {
4958       // Capture temp arrays for inscan reductions and locals in aligned
4959       // clauses.
4960       for (OMPClause *C : Clauses) {
4961         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4962           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4963             continue;
4964           for (Expr *E : RC->copy_array_temps())
4965             MarkDeclarationsReferencedInExpr(E);
4966         }
4967         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4968           for (Expr *E : AC->varlists())
4969             MarkDeclarationsReferencedInExpr(E);
4970         }
4971       }
4972     }
4973     if (++CompletedRegions == CaptureRegions.size())
4974       DSAStack->setBodyComplete();
4975     SR = ActOnCapturedRegionEnd(SR.get());
4976   }
4977   return SR;
4978 }
4979 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4980 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4981                               OpenMPDirectiveKind CancelRegion,
4982                               SourceLocation StartLoc) {
4983   // CancelRegion is only needed for cancel and cancellation_point.
4984   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4985     return false;
4986 
4987   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4988       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4989     return false;
4990 
4991   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4992       << getOpenMPDirectiveName(CancelRegion);
4993   return true;
4994 }
4995 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,OpenMPBindClauseKind BindKind,SourceLocation StartLoc)4996 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4997                                   OpenMPDirectiveKind CurrentRegion,
4998                                   const DeclarationNameInfo &CurrentName,
4999                                   OpenMPDirectiveKind CancelRegion,
5000                                   OpenMPBindClauseKind BindKind,
5001                                   SourceLocation StartLoc) {
5002   if (Stack->getCurScope()) {
5003     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
5004     OpenMPDirectiveKind OffendingRegion = ParentRegion;
5005     bool NestingProhibited = false;
5006     bool CloseNesting = true;
5007     bool OrphanSeen = false;
5008     enum {
5009       NoRecommend,
5010       ShouldBeInParallelRegion,
5011       ShouldBeInOrderedRegion,
5012       ShouldBeInTargetRegion,
5013       ShouldBeInTeamsRegion,
5014       ShouldBeInLoopSimdRegion,
5015     } Recommend = NoRecommend;
5016     if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5017         CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5018         CurrentRegion != OMPD_parallel &&
5019         !isOpenMPCombinedParallelADirective(CurrentRegion)) {
5020       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
5021           << getOpenMPDirectiveName(CurrentRegion);
5022       return true;
5023     }
5024     if (isOpenMPSimdDirective(ParentRegion) &&
5025         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5026          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5027           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5028           CurrentRegion != OMPD_scan))) {
5029       // OpenMP [2.16, Nesting of Regions]
5030       // OpenMP constructs may not be nested inside a simd region.
5031       // OpenMP [2.8.1,simd Construct, Restrictions]
5032       // An ordered construct with the simd clause is the only OpenMP
5033       // construct that can appear in the simd region.
5034       // Allowing a SIMD construct nested in another SIMD construct is an
5035       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
5036       // message.
5037       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
5038       // The only OpenMP constructs that can be encountered during execution of
5039       // a simd region are the atomic construct, the loop construct, the simd
5040       // construct and the ordered construct with the simd clause.
5041       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5042                                  ? diag::err_omp_prohibited_region_simd
5043                                  : diag::warn_omp_nesting_simd)
5044           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
5045       return CurrentRegion != OMPD_simd;
5046     }
5047     if (ParentRegion == OMPD_atomic) {
5048       // OpenMP [2.16, Nesting of Regions]
5049       // OpenMP constructs may not be nested inside an atomic region.
5050       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5051       return true;
5052     }
5053     if (CurrentRegion == OMPD_section) {
5054       // OpenMP [2.7.2, sections Construct, Restrictions]
5055       // Orphaned section directives are prohibited. That is, the section
5056       // directives must appear within the sections construct and must not be
5057       // encountered elsewhere in the sections region.
5058       if (ParentRegion != OMPD_sections &&
5059           ParentRegion != OMPD_parallel_sections) {
5060         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5061             << (ParentRegion != OMPD_unknown)
5062             << getOpenMPDirectiveName(ParentRegion);
5063         return true;
5064       }
5065       return false;
5066     }
5067     // Allow some constructs (except teams and cancellation constructs) to be
5068     // orphaned (they could be used in functions, called from OpenMP regions
5069     // with the required preconditions).
5070     if (ParentRegion == OMPD_unknown &&
5071         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
5072         CurrentRegion != OMPD_cancellation_point &&
5073         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5074       return false;
5075     // Checks needed for mapping "loop" construct. Please check mapLoopConstruct
5076     // for a detailed explanation
5077     if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
5078         (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
5079         (isOpenMPWorksharingDirective(ParentRegion) ||
5080          ParentRegion == OMPD_loop)) {
5081       int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
5082       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5083           << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
5084           << getOpenMPDirectiveName(CurrentRegion);
5085       return true;
5086     }
5087     if (CurrentRegion == OMPD_cancellation_point ||
5088         CurrentRegion == OMPD_cancel) {
5089       // OpenMP [2.16, Nesting of Regions]
5090       // A cancellation point construct for which construct-type-clause is
5091       // taskgroup must be nested inside a task construct. A cancellation
5092       // point construct for which construct-type-clause is not taskgroup must
5093       // be closely nested inside an OpenMP construct that matches the type
5094       // specified in construct-type-clause.
5095       // A cancel construct for which construct-type-clause is taskgroup must be
5096       // nested inside a task construct. A cancel construct for which
5097       // construct-type-clause is not taskgroup must be closely nested inside an
5098       // OpenMP construct that matches the type specified in
5099       // construct-type-clause.
5100       NestingProhibited =
5101           !((CancelRegion == OMPD_parallel &&
5102              (ParentRegion == OMPD_parallel ||
5103               ParentRegion == OMPD_target_parallel)) ||
5104             (CancelRegion == OMPD_for &&
5105              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5106               ParentRegion == OMPD_target_parallel_for ||
5107               ParentRegion == OMPD_distribute_parallel_for ||
5108               ParentRegion == OMPD_teams_distribute_parallel_for ||
5109               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5110             (CancelRegion == OMPD_taskgroup &&
5111              (ParentRegion == OMPD_task ||
5112               (SemaRef.getLangOpts().OpenMP >= 50 &&
5113                (ParentRegion == OMPD_taskloop ||
5114                 ParentRegion == OMPD_master_taskloop ||
5115                 ParentRegion == OMPD_masked_taskloop ||
5116                 ParentRegion == OMPD_parallel_masked_taskloop ||
5117                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5118             (CancelRegion == OMPD_sections &&
5119              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5120               ParentRegion == OMPD_parallel_sections)));
5121       OrphanSeen = ParentRegion == OMPD_unknown;
5122     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5123       // OpenMP 5.1 [2.22, Nesting of Regions]
5124       // A masked region may not be closely nested inside a worksharing, loop,
5125       // atomic, task, or taskloop region.
5126       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5127                           isOpenMPGenericLoopDirective(ParentRegion) ||
5128                           isOpenMPTaskingDirective(ParentRegion);
5129     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5130       // OpenMP [2.16, Nesting of Regions]
5131       // A critical region may not be nested (closely or otherwise) inside a
5132       // critical region with the same name. Note that this restriction is not
5133       // sufficient to prevent deadlock.
5134       SourceLocation PreviousCriticalLoc;
5135       bool DeadLock = Stack->hasDirective(
5136           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5137                                               const DeclarationNameInfo &DNI,
5138                                               SourceLocation Loc) {
5139             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5140               PreviousCriticalLoc = Loc;
5141               return true;
5142             }
5143             return false;
5144           },
5145           false /* skip top directive */);
5146       if (DeadLock) {
5147         SemaRef.Diag(StartLoc,
5148                      diag::err_omp_prohibited_region_critical_same_name)
5149             << CurrentName.getName();
5150         if (PreviousCriticalLoc.isValid())
5151           SemaRef.Diag(PreviousCriticalLoc,
5152                        diag::note_omp_previous_critical_region);
5153         return true;
5154       }
5155     } else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5156       // OpenMP 5.1 [2.22, Nesting of Regions]
5157       // A scope region may not be closely nested inside a worksharing, loop,
5158       // task, taskloop, critical, ordered, atomic, or masked region.
5159       // OpenMP 5.1 [2.22, Nesting of Regions]
5160       // A barrier region may not be closely nested inside a worksharing, loop,
5161       // task, taskloop, critical, ordered, atomic, or masked region.
5162       NestingProhibited =
5163           isOpenMPWorksharingDirective(ParentRegion) ||
5164           isOpenMPGenericLoopDirective(ParentRegion) ||
5165           isOpenMPTaskingDirective(ParentRegion) ||
5166           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5167           ParentRegion == OMPD_parallel_master ||
5168           ParentRegion == OMPD_parallel_masked ||
5169           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5170     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5171                !isOpenMPParallelDirective(CurrentRegion) &&
5172                !isOpenMPTeamsDirective(CurrentRegion)) {
5173       // OpenMP 5.1 [2.22, Nesting of Regions]
5174       // A loop region that binds to a parallel region or a worksharing region
5175       // may not be closely nested inside a worksharing, loop, task, taskloop,
5176       // critical, ordered, atomic, or masked region.
5177       NestingProhibited =
5178           isOpenMPWorksharingDirective(ParentRegion) ||
5179           isOpenMPGenericLoopDirective(ParentRegion) ||
5180           isOpenMPTaskingDirective(ParentRegion) ||
5181           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5182           ParentRegion == OMPD_parallel_master ||
5183           ParentRegion == OMPD_parallel_masked ||
5184           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5185       Recommend = ShouldBeInParallelRegion;
5186     } else if (CurrentRegion == OMPD_ordered) {
5187       // OpenMP [2.16, Nesting of Regions]
5188       // An ordered region may not be closely nested inside a critical,
5189       // atomic, or explicit task region.
5190       // An ordered region must be closely nested inside a loop region (or
5191       // parallel loop region) with an ordered clause.
5192       // OpenMP [2.8.1,simd Construct, Restrictions]
5193       // An ordered construct with the simd clause is the only OpenMP construct
5194       // that can appear in the simd region.
5195       NestingProhibited = ParentRegion == OMPD_critical ||
5196                           isOpenMPTaskingDirective(ParentRegion) ||
5197                           !(isOpenMPSimdDirective(ParentRegion) ||
5198                             Stack->isParentOrderedRegion());
5199       Recommend = ShouldBeInOrderedRegion;
5200     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5201       // OpenMP [2.16, Nesting of Regions]
5202       // If specified, a teams construct must be contained within a target
5203       // construct.
5204       NestingProhibited =
5205           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5206           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5207            ParentRegion != OMPD_target);
5208       OrphanSeen = ParentRegion == OMPD_unknown;
5209       Recommend = ShouldBeInTargetRegion;
5210     } else if (CurrentRegion == OMPD_scan) {
5211       // OpenMP [2.16, Nesting of Regions]
5212       // If specified, a teams construct must be contained within a target
5213       // construct.
5214       NestingProhibited =
5215           SemaRef.LangOpts.OpenMP < 50 ||
5216           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5217            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5218            ParentRegion != OMPD_parallel_for_simd);
5219       OrphanSeen = ParentRegion == OMPD_unknown;
5220       Recommend = ShouldBeInLoopSimdRegion;
5221     }
5222     if (!NestingProhibited &&
5223         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5224         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5225         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5226       // OpenMP [5.1, 2.22, Nesting of Regions]
5227       // distribute, distribute simd, distribute parallel worksharing-loop,
5228       // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5229       // including any parallel regions arising from combined constructs,
5230       // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5231       // only OpenMP regions that may be strictly nested inside the teams
5232       // region.
5233       //
5234       // As an extension, we permit atomic within teams as well.
5235       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5236                           !isOpenMPDistributeDirective(CurrentRegion) &&
5237                           CurrentRegion != OMPD_loop &&
5238                           !(SemaRef.getLangOpts().OpenMPExtensions &&
5239                             CurrentRegion == OMPD_atomic);
5240       Recommend = ShouldBeInParallelRegion;
5241     }
5242     if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5243       // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5244       // If the bind clause is present on the loop construct and binding is
5245       // teams then the corresponding loop region must be strictly nested inside
5246       // a teams region.
5247       NestingProhibited = BindKind == OMPC_BIND_teams &&
5248                           ParentRegion != OMPD_teams &&
5249                           ParentRegion != OMPD_target_teams;
5250       Recommend = ShouldBeInTeamsRegion;
5251     }
5252     if (!NestingProhibited &&
5253         isOpenMPNestingDistributeDirective(CurrentRegion)) {
5254       // OpenMP 4.5 [2.17 Nesting of Regions]
5255       // The region associated with the distribute construct must be strictly
5256       // nested inside a teams region
5257       NestingProhibited =
5258           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5259       Recommend = ShouldBeInTeamsRegion;
5260     }
5261     if (!NestingProhibited &&
5262         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5263          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5264       // OpenMP 4.5 [2.17 Nesting of Regions]
5265       // If a target, target update, target data, target enter data, or
5266       // target exit data construct is encountered during execution of a
5267       // target region, the behavior is unspecified.
5268       NestingProhibited = Stack->hasDirective(
5269           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5270                              SourceLocation) {
5271             if (isOpenMPTargetExecutionDirective(K)) {
5272               OffendingRegion = K;
5273               return true;
5274             }
5275             return false;
5276           },
5277           false /* don't skip top directive */);
5278       CloseNesting = false;
5279     }
5280     if (NestingProhibited) {
5281       if (OrphanSeen) {
5282         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5283             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5284       } else {
5285         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5286             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5287             << Recommend << getOpenMPDirectiveName(CurrentRegion);
5288       }
5289       return true;
5290     }
5291   }
5292   return false;
5293 }
5294 
5295 struct Kind2Unsigned {
5296   using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned5297   unsigned operator()(argument_type DK) { return unsigned(DK); }
5298 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)5299 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5300                            ArrayRef<OMPClause *> Clauses,
5301                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5302   bool ErrorFound = false;
5303   unsigned NamedModifiersNumber = 0;
5304   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5305   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5306   SmallVector<SourceLocation, 4> NameModifierLoc;
5307   for (const OMPClause *C : Clauses) {
5308     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5309       // At most one if clause without a directive-name-modifier can appear on
5310       // the directive.
5311       OpenMPDirectiveKind CurNM = IC->getNameModifier();
5312       if (FoundNameModifiers[CurNM]) {
5313         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5314             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5315             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5316         ErrorFound = true;
5317       } else if (CurNM != OMPD_unknown) {
5318         NameModifierLoc.push_back(IC->getNameModifierLoc());
5319         ++NamedModifiersNumber;
5320       }
5321       FoundNameModifiers[CurNM] = IC;
5322       if (CurNM == OMPD_unknown)
5323         continue;
5324       // Check if the specified name modifier is allowed for the current
5325       // directive.
5326       // At most one if clause with the particular directive-name-modifier can
5327       // appear on the directive.
5328       if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5329         S.Diag(IC->getNameModifierLoc(),
5330                diag::err_omp_wrong_if_directive_name_modifier)
5331             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5332         ErrorFound = true;
5333       }
5334     }
5335   }
5336   // If any if clause on the directive includes a directive-name-modifier then
5337   // all if clauses on the directive must include a directive-name-modifier.
5338   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5339     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5340       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5341              diag::err_omp_no_more_if_clause);
5342     } else {
5343       std::string Values;
5344       std::string Sep(", ");
5345       unsigned AllowedCnt = 0;
5346       unsigned TotalAllowedNum =
5347           AllowedNameModifiers.size() - NamedModifiersNumber;
5348       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5349            ++Cnt) {
5350         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5351         if (!FoundNameModifiers[NM]) {
5352           Values += "'";
5353           Values += getOpenMPDirectiveName(NM);
5354           Values += "'";
5355           if (AllowedCnt + 2 == TotalAllowedNum)
5356             Values += " or ";
5357           else if (AllowedCnt + 1 != TotalAllowedNum)
5358             Values += Sep;
5359           ++AllowedCnt;
5360         }
5361       }
5362       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5363              diag::err_omp_unnamed_if_clause)
5364           << (TotalAllowedNum > 1) << Values;
5365     }
5366     for (SourceLocation Loc : NameModifierLoc) {
5367       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5368     }
5369     ErrorFound = true;
5370   }
5371   return ErrorFound;
5372 }
5373 
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection,StringRef DiagType)5374 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5375                                                    SourceLocation &ELoc,
5376                                                    SourceRange &ERange,
5377                                                    bool AllowArraySection,
5378                                                    StringRef DiagType) {
5379   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5380       RefExpr->containsUnexpandedParameterPack())
5381     return std::make_pair(nullptr, true);
5382 
5383   // OpenMP [3.1, C/C++]
5384   //  A list item is a variable name.
5385   // OpenMP  [2.9.3.3, Restrictions, p.1]
5386   //  A variable that is part of another variable (as an array or
5387   //  structure element) cannot appear in a private clause.
5388   RefExpr = RefExpr->IgnoreParens();
5389   enum {
5390     NoArrayExpr = -1,
5391     ArraySubscript = 0,
5392     OMPArraySection = 1
5393   } IsArrayExpr = NoArrayExpr;
5394   if (AllowArraySection) {
5395     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5396       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5397       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5398         Base = TempASE->getBase()->IgnoreParenImpCasts();
5399       RefExpr = Base;
5400       IsArrayExpr = ArraySubscript;
5401     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5402       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5403       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5404         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5405       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5406         Base = TempASE->getBase()->IgnoreParenImpCasts();
5407       RefExpr = Base;
5408       IsArrayExpr = OMPArraySection;
5409     }
5410   }
5411   ELoc = RefExpr->getExprLoc();
5412   ERange = RefExpr->getSourceRange();
5413   RefExpr = RefExpr->IgnoreParenImpCasts();
5414   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5415   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5416   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5417       (S.getCurrentThisType().isNull() || !ME ||
5418        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5419        !isa<FieldDecl>(ME->getMemberDecl()))) {
5420     if (IsArrayExpr != NoArrayExpr) {
5421       S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5422           << IsArrayExpr << ERange;
5423     } else if (!DiagType.empty()) {
5424       unsigned DiagSelect = S.getLangOpts().CPlusPlus
5425                                 ? (S.getCurrentThisType().isNull() ? 1 : 2)
5426                                 : 0;
5427       S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5428           << DiagSelect << DiagType << ERange;
5429     } else {
5430       S.Diag(ELoc,
5431              AllowArraySection
5432                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5433                  : diag::err_omp_expected_var_name_member_expr)
5434           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5435     }
5436     return std::make_pair(nullptr, false);
5437   }
5438   return std::make_pair(
5439       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5440 }
5441 
5442 namespace {
5443 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5444 /// target regions.
5445 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5446   DSAStackTy *S = nullptr;
5447 
5448 public:
VisitDeclRefExpr(const DeclRefExpr * E)5449   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5450     return S->isUsesAllocatorsDecl(E->getDecl())
5451                .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5452            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5453   }
VisitStmt(const Stmt * S)5454   bool VisitStmt(const Stmt *S) {
5455     for (const Stmt *Child : S->children()) {
5456       if (Child && Visit(Child))
5457         return true;
5458     }
5459     return false;
5460   }
AllocatorChecker(DSAStackTy * S)5461   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5462 };
5463 } // namespace
5464 
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5465 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5466                                  ArrayRef<OMPClause *> Clauses) {
5467   assert(!S.CurContext->isDependentContext() &&
5468          "Expected non-dependent context.");
5469   auto AllocateRange =
5470       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5471   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5472   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5473     return isOpenMPPrivate(C->getClauseKind());
5474   });
5475   for (OMPClause *Cl : PrivateRange) {
5476     MutableArrayRef<Expr *>::iterator I, It, Et;
5477     if (Cl->getClauseKind() == OMPC_private) {
5478       auto *PC = cast<OMPPrivateClause>(Cl);
5479       I = PC->private_copies().begin();
5480       It = PC->varlist_begin();
5481       Et = PC->varlist_end();
5482     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5483       auto *PC = cast<OMPFirstprivateClause>(Cl);
5484       I = PC->private_copies().begin();
5485       It = PC->varlist_begin();
5486       Et = PC->varlist_end();
5487     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5488       auto *PC = cast<OMPLastprivateClause>(Cl);
5489       I = PC->private_copies().begin();
5490       It = PC->varlist_begin();
5491       Et = PC->varlist_end();
5492     } else if (Cl->getClauseKind() == OMPC_linear) {
5493       auto *PC = cast<OMPLinearClause>(Cl);
5494       I = PC->privates().begin();
5495       It = PC->varlist_begin();
5496       Et = PC->varlist_end();
5497     } else if (Cl->getClauseKind() == OMPC_reduction) {
5498       auto *PC = cast<OMPReductionClause>(Cl);
5499       I = PC->privates().begin();
5500       It = PC->varlist_begin();
5501       Et = PC->varlist_end();
5502     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5503       auto *PC = cast<OMPTaskReductionClause>(Cl);
5504       I = PC->privates().begin();
5505       It = PC->varlist_begin();
5506       Et = PC->varlist_end();
5507     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5508       auto *PC = cast<OMPInReductionClause>(Cl);
5509       I = PC->privates().begin();
5510       It = PC->varlist_begin();
5511       Et = PC->varlist_end();
5512     } else {
5513       llvm_unreachable("Expected private clause.");
5514     }
5515     for (Expr *E : llvm::make_range(It, Et)) {
5516       if (!*I) {
5517         ++I;
5518         continue;
5519       }
5520       SourceLocation ELoc;
5521       SourceRange ERange;
5522       Expr *SimpleRefExpr = E;
5523       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5524                                 /*AllowArraySection=*/true);
5525       DeclToCopy.try_emplace(Res.first,
5526                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5527       ++I;
5528     }
5529   }
5530   for (OMPClause *C : AllocateRange) {
5531     auto *AC = cast<OMPAllocateClause>(C);
5532     if (S.getLangOpts().OpenMP >= 50 &&
5533         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5534         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5535         AC->getAllocator()) {
5536       Expr *Allocator = AC->getAllocator();
5537       // OpenMP, 2.12.5 target Construct
5538       // Memory allocators that do not appear in a uses_allocators clause cannot
5539       // appear as an allocator in an allocate clause or be used in the target
5540       // region unless a requires directive with the dynamic_allocators clause
5541       // is present in the same compilation unit.
5542       AllocatorChecker Checker(Stack);
5543       if (Checker.Visit(Allocator))
5544         S.Diag(Allocator->getExprLoc(),
5545                diag::err_omp_allocator_not_in_uses_allocators)
5546             << Allocator->getSourceRange();
5547     }
5548     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5549         getAllocatorKind(S, Stack, AC->getAllocator());
5550     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5551     // For task, taskloop or target directives, allocation requests to memory
5552     // allocators with the trait access set to thread result in unspecified
5553     // behavior.
5554     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5555         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5556          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5557       S.Diag(AC->getAllocator()->getExprLoc(),
5558              diag::warn_omp_allocate_thread_on_task_target_directive)
5559           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5560     }
5561     for (Expr *E : AC->varlists()) {
5562       SourceLocation ELoc;
5563       SourceRange ERange;
5564       Expr *SimpleRefExpr = E;
5565       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5566       ValueDecl *VD = Res.first;
5567       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5568       if (!isOpenMPPrivate(Data.CKind)) {
5569         S.Diag(E->getExprLoc(),
5570                diag::err_omp_expected_private_copy_for_allocate);
5571         continue;
5572       }
5573       VarDecl *PrivateVD = DeclToCopy[VD];
5574       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5575                                             AllocatorKind, AC->getAllocator()))
5576         continue;
5577       // Placeholder until allocate clause supports align modifier.
5578       Expr *Alignment = nullptr;
5579       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5580                                 Alignment, E->getSourceRange());
5581     }
5582   }
5583 }
5584 
5585 namespace {
5586 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5587 ///
5588 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5589 /// context. DeclRefExpr used inside the new context are changed to refer to the
5590 /// captured variable instead.
5591 class CaptureVars : public TreeTransform<CaptureVars> {
5592   using BaseTransform = TreeTransform<CaptureVars>;
5593 
5594 public:
CaptureVars(Sema & Actions)5595   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5596 
AlwaysRebuild()5597   bool AlwaysRebuild() { return true; }
5598 };
5599 } // namespace
5600 
precomputeExpr(Sema & Actions,SmallVectorImpl<Stmt * > & BodyStmts,Expr * E,StringRef Name)5601 static VarDecl *precomputeExpr(Sema &Actions,
5602                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5603                                StringRef Name) {
5604   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5605   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5606                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5607   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5608       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5609   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5610   BodyStmts.push_back(NewDeclStmt);
5611   return NewVar;
5612 }
5613 
5614 /// Create a closure that computes the number of iterations of a loop.
5615 ///
5616 /// \param Actions   The Sema object.
5617 /// \param LogicalTy Type for the logical iteration number.
5618 /// \param Rel       Comparison operator of the loop condition.
5619 /// \param StartExpr Value of the loop counter at the first iteration.
5620 /// \param StopExpr  Expression the loop counter is compared against in the loop
5621 /// condition. \param StepExpr      Amount of increment after each iteration.
5622 ///
5623 /// \return Closure (CapturedStmt) of the distance calculation.
buildDistanceFunc(Sema & Actions,QualType LogicalTy,BinaryOperator::Opcode Rel,Expr * StartExpr,Expr * StopExpr,Expr * StepExpr)5624 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5625                                        BinaryOperator::Opcode Rel,
5626                                        Expr *StartExpr, Expr *StopExpr,
5627                                        Expr *StepExpr) {
5628   ASTContext &Ctx = Actions.getASTContext();
5629   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5630 
5631   // Captured regions currently don't support return values, we use an
5632   // out-parameter instead. All inputs are implicit captures.
5633   // TODO: Instead of capturing each DeclRefExpr occurring in
5634   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5635   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5636   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5637                                           {StringRef(), QualType()}};
5638   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5639 
5640   Stmt *Body;
5641   {
5642     Sema::CompoundScopeRAII CompoundScope(Actions);
5643     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5644 
5645     // Get the LValue expression for the result.
5646     ImplicitParamDecl *DistParam = CS->getParam(0);
5647     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5648         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5649 
5650     SmallVector<Stmt *, 4> BodyStmts;
5651 
5652     // Capture all referenced variable references.
5653     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5654     // CapturedStmt, we could compute them before and capture the result, to be
5655     // used jointly with the LoopVar function.
5656     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5657     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5658     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5659     auto BuildVarRef = [&](VarDecl *VD) {
5660       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5661     };
5662 
5663     IntegerLiteral *Zero = IntegerLiteral::Create(
5664         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5665     IntegerLiteral *One = IntegerLiteral::Create(
5666         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5667     Expr *Dist;
5668     if (Rel == BO_NE) {
5669       // When using a != comparison, the increment can be +1 or -1. This can be
5670       // dynamic at runtime, so we need to check for the direction.
5671       Expr *IsNegStep = AssertSuccess(
5672           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5673 
5674       // Positive increment.
5675       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5676           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5677       ForwardRange = AssertSuccess(
5678           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5679       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5680           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5681 
5682       // Negative increment.
5683       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5684           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5685       BackwardRange = AssertSuccess(
5686           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5687       Expr *NegIncAmount = AssertSuccess(
5688           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5689       Expr *BackwardDist = AssertSuccess(
5690           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5691 
5692       // Use the appropriate case.
5693       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5694           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5695     } else {
5696       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5697              "Expected one of these relational operators");
5698 
5699       // We can derive the direction from any other comparison operator. It is
5700       // non well-formed OpenMP if Step increments/decrements in the other
5701       // directions. Whether at least the first iteration passes the loop
5702       // condition.
5703       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5704           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5705 
5706       // Compute the range between first and last counter value.
5707       Expr *Range;
5708       if (Rel == BO_GE || Rel == BO_GT)
5709         Range = AssertSuccess(Actions.BuildBinOp(
5710             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5711       else
5712         Range = AssertSuccess(Actions.BuildBinOp(
5713             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5714 
5715       // Ensure unsigned range space.
5716       Range =
5717           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5718 
5719       if (Rel == BO_LE || Rel == BO_GE) {
5720         // Add one to the range if the relational operator is inclusive.
5721         Range =
5722             AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5723       }
5724 
5725       // Divide by the absolute step amount. If the range is not a multiple of
5726       // the step size, rounding-up the effective upper bound ensures that the
5727       // last iteration is included.
5728       // Note that the rounding-up may cause an overflow in a temporry that
5729       // could be avoided, but would have occurred in a C-style for-loop as
5730       // well.
5731       Expr *Divisor = BuildVarRef(NewStep);
5732       if (Rel == BO_GE || Rel == BO_GT)
5733         Divisor =
5734             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5735       Expr *DivisorMinusOne =
5736           AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5737       Expr *RangeRoundUp = AssertSuccess(
5738           Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5739       Dist = AssertSuccess(
5740           Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5741 
5742       // If there is not at least one iteration, the range contains garbage. Fix
5743       // to zero in this case.
5744       Dist = AssertSuccess(
5745           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5746     }
5747 
5748     // Assign the result to the out-parameter.
5749     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5750         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5751     BodyStmts.push_back(ResultAssign);
5752 
5753     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5754   }
5755 
5756   return cast<CapturedStmt>(
5757       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5758 }
5759 
5760 /// Create a closure that computes the loop variable from the logical iteration
5761 /// number.
5762 ///
5763 /// \param Actions   The Sema object.
5764 /// \param LoopVarTy Type for the loop variable used for result value.
5765 /// \param LogicalTy Type for the logical iteration number.
5766 /// \param StartExpr Value of the loop counter at the first iteration.
5767 /// \param Step      Amount of increment after each iteration.
5768 /// \param Deref     Whether the loop variable is a dereference of the loop
5769 /// counter variable.
5770 ///
5771 /// \return Closure (CapturedStmt) of the loop value calculation.
buildLoopVarFunc(Sema & Actions,QualType LoopVarTy,QualType LogicalTy,DeclRefExpr * StartExpr,Expr * Step,bool Deref)5772 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5773                                       QualType LogicalTy,
5774                                       DeclRefExpr *StartExpr, Expr *Step,
5775                                       bool Deref) {
5776   ASTContext &Ctx = Actions.getASTContext();
5777 
5778   // Pass the result as an out-parameter. Passing as return value would require
5779   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5780   // invoke a copy constructor.
5781   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5782   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5783                                           {"Logical", LogicalTy},
5784                                           {StringRef(), QualType()}};
5785   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5786 
5787   // Capture the initial iterator which represents the LoopVar value at the
5788   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5789   // it in every iteration, capture it by value before it is modified.
5790   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5791   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5792                                             Sema::TryCapture_ExplicitByVal, {});
5793   (void)Invalid;
5794   assert(!Invalid && "Expecting capture-by-value to work.");
5795 
5796   Expr *Body;
5797   {
5798     Sema::CompoundScopeRAII CompoundScope(Actions);
5799     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5800 
5801     ImplicitParamDecl *TargetParam = CS->getParam(0);
5802     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5803         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5804     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5805     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5806         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5807 
5808     // Capture the Start expression.
5809     CaptureVars Recap(Actions);
5810     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5811     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5812 
5813     Expr *Skip = AssertSuccess(
5814         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5815     // TODO: Explicitly cast to the iterator's difference_type instead of
5816     // relying on implicit conversion.
5817     Expr *Advanced =
5818         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5819 
5820     if (Deref) {
5821       // For range-based for-loops convert the loop counter value to a concrete
5822       // loop variable value by dereferencing the iterator.
5823       Advanced =
5824           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5825     }
5826 
5827     // Assign the result to the output parameter.
5828     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5829                                             BO_Assign, TargetRef, Advanced));
5830   }
5831   return cast<CapturedStmt>(
5832       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5833 }
5834 
ActOnOpenMPCanonicalLoop(Stmt * AStmt)5835 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5836   ASTContext &Ctx = getASTContext();
5837 
5838   // Extract the common elements of ForStmt and CXXForRangeStmt:
5839   // Loop variable, repeat condition, increment
5840   Expr *Cond, *Inc;
5841   VarDecl *LIVDecl, *LUVDecl;
5842   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5843     Stmt *Init = For->getInit();
5844     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5845       // For statement declares loop variable.
5846       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5847     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5848       // For statement reuses variable.
5849       assert(LCAssign->getOpcode() == BO_Assign &&
5850              "init part must be a loop variable assignment");
5851       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5852       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5853     } else
5854       llvm_unreachable("Cannot determine loop variable");
5855     LUVDecl = LIVDecl;
5856 
5857     Cond = For->getCond();
5858     Inc = For->getInc();
5859   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5860     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5861     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5862     LUVDecl = RangeFor->getLoopVariable();
5863 
5864     Cond = RangeFor->getCond();
5865     Inc = RangeFor->getInc();
5866   } else
5867     llvm_unreachable("unhandled kind of loop");
5868 
5869   QualType CounterTy = LIVDecl->getType();
5870   QualType LVTy = LUVDecl->getType();
5871 
5872   // Analyze the loop condition.
5873   Expr *LHS, *RHS;
5874   BinaryOperator::Opcode CondRel;
5875   Cond = Cond->IgnoreImplicit();
5876   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5877     LHS = CondBinExpr->getLHS();
5878     RHS = CondBinExpr->getRHS();
5879     CondRel = CondBinExpr->getOpcode();
5880   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5881     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5882     LHS = CondCXXOp->getArg(0);
5883     RHS = CondCXXOp->getArg(1);
5884     switch (CondCXXOp->getOperator()) {
5885     case OO_ExclaimEqual:
5886       CondRel = BO_NE;
5887       break;
5888     case OO_Less:
5889       CondRel = BO_LT;
5890       break;
5891     case OO_LessEqual:
5892       CondRel = BO_LE;
5893       break;
5894     case OO_Greater:
5895       CondRel = BO_GT;
5896       break;
5897     case OO_GreaterEqual:
5898       CondRel = BO_GE;
5899       break;
5900     default:
5901       llvm_unreachable("unexpected iterator operator");
5902     }
5903   } else
5904     llvm_unreachable("unexpected loop condition");
5905 
5906   // Normalize such that the loop counter is on the LHS.
5907   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5908       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5909     std::swap(LHS, RHS);
5910     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5911   }
5912   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5913 
5914   // Decide the bit width for the logical iteration counter. By default use the
5915   // unsigned ptrdiff_t integer size (for iterators and pointers).
5916   // TODO: For iterators, use iterator::difference_type,
5917   // std::iterator_traits<>::difference_type or decltype(it - end).
5918   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5919   if (CounterTy->isIntegerType()) {
5920     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5921     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5922   }
5923 
5924   // Analyze the loop increment.
5925   Expr *Step;
5926   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5927     int Direction;
5928     switch (IncUn->getOpcode()) {
5929     case UO_PreInc:
5930     case UO_PostInc:
5931       Direction = 1;
5932       break;
5933     case UO_PreDec:
5934     case UO_PostDec:
5935       Direction = -1;
5936       break;
5937     default:
5938       llvm_unreachable("unhandled unary increment operator");
5939     }
5940     Step = IntegerLiteral::Create(
5941         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5942   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5943     if (IncBin->getOpcode() == BO_AddAssign) {
5944       Step = IncBin->getRHS();
5945     } else if (IncBin->getOpcode() == BO_SubAssign) {
5946       Step =
5947           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5948     } else
5949       llvm_unreachable("unhandled binary increment operator");
5950   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5951     switch (CondCXXOp->getOperator()) {
5952     case OO_PlusPlus:
5953       Step = IntegerLiteral::Create(
5954           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5955       break;
5956     case OO_MinusMinus:
5957       Step = IntegerLiteral::Create(
5958           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5959       break;
5960     case OO_PlusEqual:
5961       Step = CondCXXOp->getArg(1);
5962       break;
5963     case OO_MinusEqual:
5964       Step = AssertSuccess(
5965           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5966       break;
5967     default:
5968       llvm_unreachable("unhandled overloaded increment operator");
5969     }
5970   } else
5971     llvm_unreachable("unknown increment expression");
5972 
5973   CapturedStmt *DistanceFunc =
5974       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5975   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5976       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5977   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5978                                         {}, nullptr, nullptr, {}, nullptr);
5979   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5980                                   LoopVarFunc, LVRef);
5981 }
5982 
ActOnOpenMPLoopnest(Stmt * AStmt)5983 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5984   // Handle a literal loop.
5985   if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5986     return ActOnOpenMPCanonicalLoop(AStmt);
5987 
5988   // If not a literal loop, it must be the result of a loop transformation.
5989   OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5990   assert(
5991       isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5992       "Loop transformation directive expected");
5993   return LoopTransform;
5994 }
5995 
5996 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5997                                             CXXScopeSpec &MapperIdScopeSpec,
5998                                             const DeclarationNameInfo &MapperId,
5999                                             QualType Type,
6000                                             Expr *UnresolvedMapper);
6001 
6002 /// Perform DFS through the structure/class data members trying to find
6003 /// member(s) with user-defined 'default' mapper and generate implicit map
6004 /// clauses for such members with the found 'default' mapper.
6005 static void
processImplicitMapsWithDefaultMappers(Sema & S,DSAStackTy * Stack,SmallVectorImpl<OMPClause * > & Clauses)6006 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
6007                                       SmallVectorImpl<OMPClause *> &Clauses) {
6008   // Check for the deault mapper for data members.
6009   if (S.getLangOpts().OpenMP < 50)
6010     return;
6011   SmallVector<OMPClause *, 4> ImplicitMaps;
6012   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
6013     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6014     if (!C)
6015       continue;
6016     SmallVector<Expr *, 4> SubExprs;
6017     auto *MI = C->mapperlist_begin();
6018     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
6019          ++I, ++MI) {
6020       // Expression is mapped using mapper - skip it.
6021       if (*MI)
6022         continue;
6023       Expr *E = *I;
6024       // Expression is dependent - skip it, build the mapper when it gets
6025       // instantiated.
6026       if (E->isTypeDependent() || E->isValueDependent() ||
6027           E->containsUnexpandedParameterPack())
6028         continue;
6029       // Array section - need to check for the mapping of the array section
6030       // element.
6031       QualType CanonType = E->getType().getCanonicalType();
6032       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
6033         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
6034         QualType BaseType =
6035             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
6036         QualType ElemType;
6037         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
6038           ElemType = ATy->getElementType();
6039         else
6040           ElemType = BaseType->getPointeeType();
6041         CanonType = ElemType;
6042       }
6043 
6044       // DFS over data members in structures/classes.
6045       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
6046           1, {CanonType, nullptr});
6047       llvm::DenseMap<const Type *, Expr *> Visited;
6048       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
6049           1, {nullptr, 1});
6050       while (!Types.empty()) {
6051         QualType BaseType;
6052         FieldDecl *CurFD;
6053         std::tie(BaseType, CurFD) = Types.pop_back_val();
6054         while (ParentChain.back().second == 0)
6055           ParentChain.pop_back();
6056         --ParentChain.back().second;
6057         if (BaseType.isNull())
6058           continue;
6059         // Only structs/classes are allowed to have mappers.
6060         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6061         if (!RD)
6062           continue;
6063         auto It = Visited.find(BaseType.getTypePtr());
6064         if (It == Visited.end()) {
6065           // Try to find the associated user-defined mapper.
6066           CXXScopeSpec MapperIdScopeSpec;
6067           DeclarationNameInfo DefaultMapperId;
6068           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6069               &S.Context.Idents.get("default")));
6070           DefaultMapperId.setLoc(E->getExprLoc());
6071           ExprResult ER = buildUserDefinedMapperRef(
6072               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6073               BaseType, /*UnresolvedMapper=*/nullptr);
6074           if (ER.isInvalid())
6075             continue;
6076           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6077         }
6078         // Found default mapper.
6079         if (It->second) {
6080           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6081                                                      VK_LValue, OK_Ordinary, E);
6082           OE->setIsUnique(/*V=*/true);
6083           Expr *BaseExpr = OE;
6084           for (const auto &P : ParentChain) {
6085             if (P.first) {
6086               BaseExpr = S.BuildMemberExpr(
6087                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6088                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
6089                   DeclAccessPair::make(P.first, P.first->getAccess()),
6090                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6091                   P.first->getType(), VK_LValue, OK_Ordinary);
6092               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6093             }
6094           }
6095           if (CurFD)
6096             BaseExpr = S.BuildMemberExpr(
6097                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6098                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
6099                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
6100                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6101                 CurFD->getType(), VK_LValue, OK_Ordinary);
6102           SubExprs.push_back(BaseExpr);
6103           continue;
6104         }
6105         // Check for the "default" mapper for data members.
6106         bool FirstIter = true;
6107         for (FieldDecl *FD : RD->fields()) {
6108           if (!FD)
6109             continue;
6110           QualType FieldTy = FD->getType();
6111           if (FieldTy.isNull() ||
6112               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6113             continue;
6114           if (FirstIter) {
6115             FirstIter = false;
6116             ParentChain.emplace_back(CurFD, 1);
6117           } else {
6118             ++ParentChain.back().second;
6119           }
6120           Types.emplace_back(FieldTy, FD);
6121         }
6122       }
6123     }
6124     if (SubExprs.empty())
6125       continue;
6126     CXXScopeSpec MapperIdScopeSpec;
6127     DeclarationNameInfo MapperId;
6128     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6129             nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6130             MapperIdScopeSpec, MapperId, C->getMapType(),
6131             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6132             SubExprs, OMPVarListLocTy()))
6133       Clauses.push_back(NewClause);
6134   }
6135 }
6136 
mapLoopConstruct(llvm::SmallVector<OMPClause * > & ClausesWithoutBind,ArrayRef<OMPClause * > Clauses,OpenMPBindClauseKind & BindKind,OpenMPDirectiveKind & Kind,OpenMPDirectiveKind & PrevMappedDirective,SourceLocation StartLoc,SourceLocation EndLoc,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion)6137 bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
6138                             ArrayRef<OMPClause *> Clauses,
6139                             OpenMPBindClauseKind &BindKind,
6140                             OpenMPDirectiveKind &Kind,
6141                             OpenMPDirectiveKind &PrevMappedDirective,
6142                             SourceLocation StartLoc, SourceLocation EndLoc,
6143                             const DeclarationNameInfo &DirName,
6144                             OpenMPDirectiveKind CancelRegion) {
6145 
6146   bool UseClausesWithoutBind = false;
6147 
6148   // Restricting to "#pragma omp loop bind"
6149   if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6150 
6151     const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
6152 
6153     if (BindKind == OMPC_BIND_unknown) {
6154       // Setting the enclosing teams or parallel construct for the loop
6155       // directive without bind clause.
6156       BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
6157 
6158       if (ParentDirective == OMPD_unknown) {
6159         Diag(DSAStack->getDefaultDSALocation(),
6160              diag::err_omp_bind_required_on_loop);
6161       } else if (ParentDirective == OMPD_parallel ||
6162                  ParentDirective == OMPD_target_parallel) {
6163         BindKind = OMPC_BIND_parallel;
6164       } else if (ParentDirective == OMPD_teams ||
6165                  ParentDirective == OMPD_target_teams) {
6166         BindKind = OMPC_BIND_teams;
6167       }
6168     } else {
6169       // bind clause is present in loop directive. When the loop directive is
6170       // changed to a new directive the bind clause is not used. So, we should
6171       // set flag indicating to only use the clauses that aren't the
6172       // bind clause.
6173       UseClausesWithoutBind = true;
6174     }
6175 
6176     for (OMPClause *C : Clauses) {
6177       // Spec restriction : bind(teams) and reduction not permitted.
6178       if (BindKind == OMPC_BIND_teams &&
6179           C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
6180         Diag(DSAStack->getDefaultDSALocation(),
6181              diag::err_omp_loop_reduction_clause);
6182 
6183       // A new Vector ClausesWithoutBind, which does not contain the bind
6184       // clause, for passing to new directive.
6185       if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6186         ClausesWithoutBind.push_back(C);
6187     }
6188 
6189     switch (BindKind) {
6190     case OMPC_BIND_parallel:
6191       Kind = OMPD_for;
6192       DSAStack->setCurrentDirective(OMPD_for);
6193       DSAStack->setMappedDirective(OMPD_loop);
6194       PrevMappedDirective = OMPD_loop;
6195       break;
6196     case OMPC_BIND_teams:
6197       Kind = OMPD_distribute;
6198       DSAStack->setCurrentDirective(OMPD_distribute);
6199       DSAStack->setMappedDirective(OMPD_loop);
6200       PrevMappedDirective = OMPD_loop;
6201       break;
6202     case OMPC_BIND_thread:
6203       Kind = OMPD_simd;
6204       DSAStack->setCurrentDirective(OMPD_simd);
6205       DSAStack->setMappedDirective(OMPD_loop);
6206       PrevMappedDirective = OMPD_loop;
6207       break;
6208     case OMPC_BIND_unknown:
6209       break;
6210     }
6211   } else if (PrevMappedDirective == OMPD_loop) {
6212     /// An initial pass after recognizing all the statements is done in the
6213     /// Parser when the directive OMPD_loop is mapped to OMPD_for,
6214     /// OMPD_distribute or OMPD_simd. A second transform pass with call from
6215     /// clang::TreeTransform::TransformOMPExecutableDirective() is done
6216     /// with the Directive as one of the above mapped directive without
6217     /// the bind clause. Then "PrevMappedDirective" stored in the
6218     /// OMPExecutableDirective is accessed and hence this else statement.
6219 
6220     DSAStack->setMappedDirective(OMPD_loop);
6221   }
6222 
6223   return UseClausesWithoutBind;
6224 }
6225 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind PrevMappedDirective)6226 StmtResult Sema::ActOnOpenMPExecutableDirective(
6227     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6228     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6229     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
6230     OpenMPDirectiveKind PrevMappedDirective) {
6231   StmtResult Res = StmtError();
6232   OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6233   llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6234   bool UseClausesWithoutBind = false;
6235 
6236   if (const OMPBindClause *BC =
6237           OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6238     BindKind = BC->getBindKind();
6239 
6240   // Variable used to note down the DirectiveKind because mapLoopConstruct may
6241   // change "Kind" variable, due to mapping of "omp loop" to other directives.
6242   OpenMPDirectiveKind DK = Kind;
6243   if (Kind == OMPD_loop || PrevMappedDirective == OMPD_loop) {
6244     UseClausesWithoutBind = mapLoopConstruct(
6245         ClausesWithoutBind, Clauses, BindKind, Kind, PrevMappedDirective,
6246         StartLoc, EndLoc, DirName, CancelRegion);
6247     DK = OMPD_loop;
6248   }
6249 
6250   // First check CancelRegion which is then used in checkNestingOfRegions.
6251   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6252       checkNestingOfRegions(*this, DSAStack, DK, DirName, CancelRegion,
6253                             BindKind, StartLoc)) {
6254     return StmtError();
6255   }
6256 
6257   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
6258   if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
6259                             isOpenMPTargetDataManagementDirective(Kind)))
6260     Diag(StartLoc, diag::warn_hip_omp_target_directives);
6261 
6262   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6263   VarsWithInheritedDSAType VarsWithInheritedDSA;
6264   bool ErrorFound = false;
6265   if (getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
6266     ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6267                                ClausesWithoutBind.end());
6268   } else {
6269     ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6270   }
6271   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6272       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6273       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6274     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6275 
6276     // Check default data sharing attributes for referenced variables.
6277     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6278     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6279     Stmt *S = AStmt;
6280     while (--ThisCaptureLevel >= 0)
6281       S = cast<CapturedStmt>(S)->getCapturedStmt();
6282     DSAChecker.Visit(S);
6283     if (!isOpenMPTargetDataManagementDirective(Kind) &&
6284         !isOpenMPTaskingDirective(Kind)) {
6285       // Visit subcaptures to generate implicit clauses for captured vars.
6286       auto *CS = cast<CapturedStmt>(AStmt);
6287       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6288       getOpenMPCaptureRegions(CaptureRegions, Kind);
6289       // Ignore outer tasking regions for target directives.
6290       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6291         CS = cast<CapturedStmt>(CS->getCapturedStmt());
6292       DSAChecker.visitSubCaptures(CS);
6293     }
6294     if (DSAChecker.isErrorFound())
6295       return StmtError();
6296     // Generate list of implicitly defined firstprivate variables.
6297     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6298 
6299     SmallVector<Expr *, 4> ImplicitFirstprivates(
6300         DSAChecker.getImplicitFirstprivate().begin(),
6301         DSAChecker.getImplicitFirstprivate().end());
6302     SmallVector<Expr *, 4> ImplicitPrivates(
6303         DSAChecker.getImplicitPrivate().begin(),
6304         DSAChecker.getImplicitPrivate().end());
6305     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
6306     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6307     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6308         ImplicitMapModifiers[DefaultmapKindNum];
6309     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6310         ImplicitMapModifiersLoc[DefaultmapKindNum];
6311     // Get the original location of present modifier from Defaultmap clause.
6312     SourceLocation PresentModifierLocs[DefaultmapKindNum];
6313     for (OMPClause *C : Clauses) {
6314       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6315         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6316           PresentModifierLocs[DMC->getDefaultmapKind()] =
6317               DMC->getDefaultmapModifierLoc();
6318     }
6319     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6320       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6321       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6322         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6323             Kind, static_cast<OpenMPMapClauseKind>(I));
6324         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6325       }
6326       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6327           DSAChecker.getImplicitMapModifier(Kind);
6328       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6329                                       ImplicitModifier.end());
6330       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6331                   ImplicitModifier.size(), PresentModifierLocs[VC]);
6332     }
6333     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6334     for (OMPClause *C : Clauses) {
6335       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6336         for (Expr *E : IRC->taskgroup_descriptors())
6337           if (E)
6338             ImplicitFirstprivates.emplace_back(E);
6339       }
6340       // OpenMP 5.0, 2.10.1 task Construct
6341       // [detach clause]... The event-handle will be considered as if it was
6342       // specified on a firstprivate clause.
6343       if (auto *DC = dyn_cast<OMPDetachClause>(C))
6344         ImplicitFirstprivates.push_back(DC->getEventHandler());
6345     }
6346     if (!ImplicitFirstprivates.empty()) {
6347       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6348               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6349               SourceLocation())) {
6350         ClausesWithImplicit.push_back(Implicit);
6351         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6352                      ImplicitFirstprivates.size();
6353       } else {
6354         ErrorFound = true;
6355       }
6356     }
6357     if (!ImplicitPrivates.empty()) {
6358       if (OMPClause *Implicit =
6359               ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6360                                        SourceLocation(), SourceLocation())) {
6361         ClausesWithImplicit.push_back(Implicit);
6362         ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6363                      ImplicitPrivates.size();
6364       } else {
6365         ErrorFound = true;
6366       }
6367     }
6368     // OpenMP 5.0 [2.19.7]
6369     // If a list item appears in a reduction, lastprivate or linear
6370     // clause on a combined target construct then it is treated as
6371     // if it also appears in a map clause with a map-type of tofrom
6372     if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6373         isOpenMPTargetExecutionDirective(Kind)) {
6374       SmallVector<Expr *, 4> ImplicitExprs;
6375       for (OMPClause *C : Clauses) {
6376         if (auto *RC = dyn_cast<OMPReductionClause>(C))
6377           for (Expr *E : RC->varlists())
6378             if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6379               ImplicitExprs.emplace_back(E);
6380       }
6381       if (!ImplicitExprs.empty()) {
6382         ArrayRef<Expr *> Exprs = ImplicitExprs;
6383         CXXScopeSpec MapperIdScopeSpec;
6384         DeclarationNameInfo MapperId;
6385         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6386                 nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
6387                 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6388                 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6389                 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6390           ClausesWithImplicit.emplace_back(Implicit);
6391       }
6392     }
6393     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6394       int ClauseKindCnt = -1;
6395       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6396         ++ClauseKindCnt;
6397         if (ImplicitMap.empty())
6398           continue;
6399         CXXScopeSpec MapperIdScopeSpec;
6400         DeclarationNameInfo MapperId;
6401         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6402         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6403                 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6404                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6405                 SourceLocation(), SourceLocation(), ImplicitMap,
6406                 OMPVarListLocTy())) {
6407           ClausesWithImplicit.emplace_back(Implicit);
6408           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6409                         ImplicitMap.size();
6410         } else {
6411           ErrorFound = true;
6412         }
6413       }
6414     }
6415     // Build expressions for implicit maps of data members with 'default'
6416     // mappers.
6417     if (LangOpts.OpenMP >= 50)
6418       processImplicitMapsWithDefaultMappers(*this, DSAStack,
6419                                             ClausesWithImplicit);
6420   }
6421 
6422   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6423   switch (Kind) {
6424   case OMPD_parallel:
6425     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6426                                        EndLoc);
6427     AllowedNameModifiers.push_back(OMPD_parallel);
6428     break;
6429   case OMPD_simd:
6430     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6431                                    VarsWithInheritedDSA);
6432     if (LangOpts.OpenMP >= 50)
6433       AllowedNameModifiers.push_back(OMPD_simd);
6434     break;
6435   case OMPD_tile:
6436     Res =
6437         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6438     break;
6439   case OMPD_unroll:
6440     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6441                                      EndLoc);
6442     break;
6443   case OMPD_for:
6444     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6445                                   VarsWithInheritedDSA);
6446     break;
6447   case OMPD_for_simd:
6448     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6449                                       EndLoc, VarsWithInheritedDSA);
6450     if (LangOpts.OpenMP >= 50)
6451       AllowedNameModifiers.push_back(OMPD_simd);
6452     break;
6453   case OMPD_sections:
6454     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6455                                        EndLoc);
6456     break;
6457   case OMPD_section:
6458     assert(ClausesWithImplicit.empty() &&
6459            "No clauses are allowed for 'omp section' directive");
6460     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6461     break;
6462   case OMPD_single:
6463     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6464                                      EndLoc);
6465     break;
6466   case OMPD_master:
6467     assert(ClausesWithImplicit.empty() &&
6468            "No clauses are allowed for 'omp master' directive");
6469     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6470     break;
6471   case OMPD_masked:
6472     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6473                                      EndLoc);
6474     break;
6475   case OMPD_critical:
6476     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6477                                        StartLoc, EndLoc);
6478     break;
6479   case OMPD_parallel_for:
6480     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6481                                           EndLoc, VarsWithInheritedDSA);
6482     AllowedNameModifiers.push_back(OMPD_parallel);
6483     break;
6484   case OMPD_parallel_for_simd:
6485     Res = ActOnOpenMPParallelForSimdDirective(
6486         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6487     AllowedNameModifiers.push_back(OMPD_parallel);
6488     if (LangOpts.OpenMP >= 50)
6489       AllowedNameModifiers.push_back(OMPD_simd);
6490     break;
6491   case OMPD_scope:
6492     Res =
6493         ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6494     break;
6495   case OMPD_parallel_master:
6496     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6497                                              StartLoc, EndLoc);
6498     AllowedNameModifiers.push_back(OMPD_parallel);
6499     break;
6500   case OMPD_parallel_masked:
6501     Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6502                                              StartLoc, EndLoc);
6503     AllowedNameModifiers.push_back(OMPD_parallel);
6504     break;
6505   case OMPD_parallel_sections:
6506     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6507                                                StartLoc, EndLoc);
6508     AllowedNameModifiers.push_back(OMPD_parallel);
6509     break;
6510   case OMPD_task:
6511     Res =
6512         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6513     AllowedNameModifiers.push_back(OMPD_task);
6514     break;
6515   case OMPD_taskyield:
6516     assert(ClausesWithImplicit.empty() &&
6517            "No clauses are allowed for 'omp taskyield' directive");
6518     assert(AStmt == nullptr &&
6519            "No associated statement allowed for 'omp taskyield' directive");
6520     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6521     break;
6522   case OMPD_error:
6523     assert(AStmt == nullptr &&
6524            "No associated statement allowed for 'omp error' directive");
6525     Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6526     break;
6527   case OMPD_barrier:
6528     assert(ClausesWithImplicit.empty() &&
6529            "No clauses are allowed for 'omp barrier' directive");
6530     assert(AStmt == nullptr &&
6531            "No associated statement allowed for 'omp barrier' directive");
6532     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6533     break;
6534   case OMPD_taskwait:
6535     assert(AStmt == nullptr &&
6536            "No associated statement allowed for 'omp taskwait' directive");
6537     Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6538     break;
6539   case OMPD_taskgroup:
6540     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6541                                         EndLoc);
6542     break;
6543   case OMPD_flush:
6544     assert(AStmt == nullptr &&
6545            "No associated statement allowed for 'omp flush' directive");
6546     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6547     break;
6548   case OMPD_depobj:
6549     assert(AStmt == nullptr &&
6550            "No associated statement allowed for 'omp depobj' directive");
6551     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6552     break;
6553   case OMPD_scan:
6554     assert(AStmt == nullptr &&
6555            "No associated statement allowed for 'omp scan' directive");
6556     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6557     break;
6558   case OMPD_ordered:
6559     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6560                                       EndLoc);
6561     break;
6562   case OMPD_atomic:
6563     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6564                                      EndLoc);
6565     break;
6566   case OMPD_teams:
6567     Res =
6568         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6569     break;
6570   case OMPD_target:
6571     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6572                                      EndLoc);
6573     AllowedNameModifiers.push_back(OMPD_target);
6574     break;
6575   case OMPD_target_parallel:
6576     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6577                                              StartLoc, EndLoc);
6578     AllowedNameModifiers.push_back(OMPD_target);
6579     AllowedNameModifiers.push_back(OMPD_parallel);
6580     break;
6581   case OMPD_target_parallel_for:
6582     Res = ActOnOpenMPTargetParallelForDirective(
6583         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6584     AllowedNameModifiers.push_back(OMPD_target);
6585     AllowedNameModifiers.push_back(OMPD_parallel);
6586     break;
6587   case OMPD_cancellation_point:
6588     assert(ClausesWithImplicit.empty() &&
6589            "No clauses are allowed for 'omp cancellation point' directive");
6590     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6591                                "cancellation point' directive");
6592     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6593     break;
6594   case OMPD_cancel:
6595     assert(AStmt == nullptr &&
6596            "No associated statement allowed for 'omp cancel' directive");
6597     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6598                                      CancelRegion);
6599     AllowedNameModifiers.push_back(OMPD_cancel);
6600     break;
6601   case OMPD_target_data:
6602     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6603                                          EndLoc);
6604     AllowedNameModifiers.push_back(OMPD_target_data);
6605     break;
6606   case OMPD_target_enter_data:
6607     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6608                                               EndLoc, AStmt);
6609     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6610     break;
6611   case OMPD_target_exit_data:
6612     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6613                                              EndLoc, AStmt);
6614     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6615     break;
6616   case OMPD_taskloop:
6617     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6618                                        EndLoc, VarsWithInheritedDSA);
6619     AllowedNameModifiers.push_back(OMPD_taskloop);
6620     break;
6621   case OMPD_taskloop_simd:
6622     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6623                                            EndLoc, VarsWithInheritedDSA);
6624     AllowedNameModifiers.push_back(OMPD_taskloop);
6625     if (LangOpts.OpenMP >= 50)
6626       AllowedNameModifiers.push_back(OMPD_simd);
6627     break;
6628   case OMPD_master_taskloop:
6629     Res = ActOnOpenMPMasterTaskLoopDirective(
6630         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6631     AllowedNameModifiers.push_back(OMPD_taskloop);
6632     break;
6633   case OMPD_masked_taskloop:
6634     Res = ActOnOpenMPMaskedTaskLoopDirective(
6635         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6636     AllowedNameModifiers.push_back(OMPD_taskloop);
6637     break;
6638   case OMPD_master_taskloop_simd:
6639     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6640         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6641     AllowedNameModifiers.push_back(OMPD_taskloop);
6642     if (LangOpts.OpenMP >= 50)
6643       AllowedNameModifiers.push_back(OMPD_simd);
6644     break;
6645   case OMPD_masked_taskloop_simd:
6646     Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6647         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6648     if (LangOpts.OpenMP >= 51) {
6649       AllowedNameModifiers.push_back(OMPD_taskloop);
6650       AllowedNameModifiers.push_back(OMPD_simd);
6651     }
6652     break;
6653   case OMPD_parallel_master_taskloop:
6654     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6655         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6656     AllowedNameModifiers.push_back(OMPD_taskloop);
6657     AllowedNameModifiers.push_back(OMPD_parallel);
6658     break;
6659   case OMPD_parallel_masked_taskloop:
6660     Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6661         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6662     if (LangOpts.OpenMP >= 51) {
6663       AllowedNameModifiers.push_back(OMPD_taskloop);
6664       AllowedNameModifiers.push_back(OMPD_parallel);
6665     }
6666     break;
6667   case OMPD_parallel_master_taskloop_simd:
6668     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6669         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6670     AllowedNameModifiers.push_back(OMPD_taskloop);
6671     AllowedNameModifiers.push_back(OMPD_parallel);
6672     if (LangOpts.OpenMP >= 50)
6673       AllowedNameModifiers.push_back(OMPD_simd);
6674     break;
6675   case OMPD_parallel_masked_taskloop_simd:
6676     Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6677         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6678     if (LangOpts.OpenMP >= 51) {
6679       AllowedNameModifiers.push_back(OMPD_taskloop);
6680       AllowedNameModifiers.push_back(OMPD_parallel);
6681       AllowedNameModifiers.push_back(OMPD_simd);
6682     }
6683     break;
6684   case OMPD_distribute:
6685     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6686                                          EndLoc, VarsWithInheritedDSA);
6687     break;
6688   case OMPD_target_update:
6689     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6690                                            EndLoc, AStmt);
6691     AllowedNameModifiers.push_back(OMPD_target_update);
6692     break;
6693   case OMPD_distribute_parallel_for:
6694     Res = ActOnOpenMPDistributeParallelForDirective(
6695         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6696     AllowedNameModifiers.push_back(OMPD_parallel);
6697     break;
6698   case OMPD_distribute_parallel_for_simd:
6699     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6700         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6701     AllowedNameModifiers.push_back(OMPD_parallel);
6702     if (LangOpts.OpenMP >= 50)
6703       AllowedNameModifiers.push_back(OMPD_simd);
6704     break;
6705   case OMPD_distribute_simd:
6706     Res = ActOnOpenMPDistributeSimdDirective(
6707         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6708     if (LangOpts.OpenMP >= 50)
6709       AllowedNameModifiers.push_back(OMPD_simd);
6710     break;
6711   case OMPD_target_parallel_for_simd:
6712     Res = ActOnOpenMPTargetParallelForSimdDirective(
6713         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6714     AllowedNameModifiers.push_back(OMPD_target);
6715     AllowedNameModifiers.push_back(OMPD_parallel);
6716     if (LangOpts.OpenMP >= 50)
6717       AllowedNameModifiers.push_back(OMPD_simd);
6718     break;
6719   case OMPD_target_simd:
6720     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6721                                          EndLoc, VarsWithInheritedDSA);
6722     AllowedNameModifiers.push_back(OMPD_target);
6723     if (LangOpts.OpenMP >= 50)
6724       AllowedNameModifiers.push_back(OMPD_simd);
6725     break;
6726   case OMPD_teams_distribute:
6727     Res = ActOnOpenMPTeamsDistributeDirective(
6728         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6729     break;
6730   case OMPD_teams_distribute_simd:
6731     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6732         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6733     if (LangOpts.OpenMP >= 50)
6734       AllowedNameModifiers.push_back(OMPD_simd);
6735     break;
6736   case OMPD_teams_distribute_parallel_for_simd:
6737     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6738         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6739     AllowedNameModifiers.push_back(OMPD_parallel);
6740     if (LangOpts.OpenMP >= 50)
6741       AllowedNameModifiers.push_back(OMPD_simd);
6742     break;
6743   case OMPD_teams_distribute_parallel_for:
6744     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6745         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6746     AllowedNameModifiers.push_back(OMPD_parallel);
6747     break;
6748   case OMPD_target_teams:
6749     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6750                                           EndLoc);
6751     AllowedNameModifiers.push_back(OMPD_target);
6752     break;
6753   case OMPD_target_teams_distribute:
6754     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6755         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6756     AllowedNameModifiers.push_back(OMPD_target);
6757     break;
6758   case OMPD_target_teams_distribute_parallel_for:
6759     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6760         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6761     AllowedNameModifiers.push_back(OMPD_target);
6762     AllowedNameModifiers.push_back(OMPD_parallel);
6763     break;
6764   case OMPD_target_teams_distribute_parallel_for_simd:
6765     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6766         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6767     AllowedNameModifiers.push_back(OMPD_target);
6768     AllowedNameModifiers.push_back(OMPD_parallel);
6769     if (LangOpts.OpenMP >= 50)
6770       AllowedNameModifiers.push_back(OMPD_simd);
6771     break;
6772   case OMPD_target_teams_distribute_simd:
6773     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6774         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6775     AllowedNameModifiers.push_back(OMPD_target);
6776     if (LangOpts.OpenMP >= 50)
6777       AllowedNameModifiers.push_back(OMPD_simd);
6778     break;
6779   case OMPD_interop:
6780     assert(AStmt == nullptr &&
6781            "No associated statement allowed for 'omp interop' directive");
6782     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6783     break;
6784   case OMPD_dispatch:
6785     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6786                                        EndLoc);
6787     break;
6788   case OMPD_loop:
6789     Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6790                                           EndLoc, VarsWithInheritedDSA);
6791     break;
6792   case OMPD_teams_loop:
6793     Res = ActOnOpenMPTeamsGenericLoopDirective(
6794         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6795     break;
6796   case OMPD_target_teams_loop:
6797     Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6798         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6799     AllowedNameModifiers.push_back(OMPD_target);
6800     break;
6801   case OMPD_parallel_loop:
6802     Res = ActOnOpenMPParallelGenericLoopDirective(
6803         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6804     break;
6805   case OMPD_target_parallel_loop:
6806     Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6807         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6808     break;
6809   case OMPD_declare_target:
6810   case OMPD_end_declare_target:
6811   case OMPD_threadprivate:
6812   case OMPD_allocate:
6813   case OMPD_declare_reduction:
6814   case OMPD_declare_mapper:
6815   case OMPD_declare_simd:
6816   case OMPD_requires:
6817   case OMPD_declare_variant:
6818   case OMPD_begin_declare_variant:
6819   case OMPD_end_declare_variant:
6820     llvm_unreachable("OpenMP Directive is not allowed");
6821   case OMPD_unknown:
6822   default:
6823     llvm_unreachable("Unknown OpenMP directive");
6824   }
6825 
6826   ErrorFound = Res.isInvalid() || ErrorFound;
6827 
6828   // Check variables in the clauses if default(none) or
6829   // default(firstprivate) was specified.
6830   if (DSAStack->getDefaultDSA() == DSA_none ||
6831       DSAStack->getDefaultDSA() == DSA_private ||
6832       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6833     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6834     for (OMPClause *C : Clauses) {
6835       switch (C->getClauseKind()) {
6836       case OMPC_num_threads:
6837       case OMPC_dist_schedule:
6838         // Do not analyse if no parent teams directive.
6839         if (isOpenMPTeamsDirective(Kind))
6840           break;
6841         continue;
6842       case OMPC_if:
6843         if (isOpenMPTeamsDirective(Kind) &&
6844             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6845           break;
6846         if (isOpenMPParallelDirective(Kind) &&
6847             isOpenMPTaskLoopDirective(Kind) &&
6848             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6849           break;
6850         continue;
6851       case OMPC_schedule:
6852       case OMPC_detach:
6853         break;
6854       case OMPC_grainsize:
6855       case OMPC_num_tasks:
6856       case OMPC_final:
6857       case OMPC_priority:
6858       case OMPC_novariants:
6859       case OMPC_nocontext:
6860         // Do not analyze if no parent parallel directive.
6861         if (isOpenMPParallelDirective(Kind))
6862           break;
6863         continue;
6864       case OMPC_ordered:
6865       case OMPC_device:
6866       case OMPC_num_teams:
6867       case OMPC_thread_limit:
6868       case OMPC_hint:
6869       case OMPC_collapse:
6870       case OMPC_safelen:
6871       case OMPC_simdlen:
6872       case OMPC_sizes:
6873       case OMPC_default:
6874       case OMPC_proc_bind:
6875       case OMPC_private:
6876       case OMPC_firstprivate:
6877       case OMPC_lastprivate:
6878       case OMPC_shared:
6879       case OMPC_reduction:
6880       case OMPC_task_reduction:
6881       case OMPC_in_reduction:
6882       case OMPC_linear:
6883       case OMPC_aligned:
6884       case OMPC_copyin:
6885       case OMPC_copyprivate:
6886       case OMPC_nowait:
6887       case OMPC_untied:
6888       case OMPC_mergeable:
6889       case OMPC_allocate:
6890       case OMPC_read:
6891       case OMPC_write:
6892       case OMPC_update:
6893       case OMPC_capture:
6894       case OMPC_compare:
6895       case OMPC_seq_cst:
6896       case OMPC_acq_rel:
6897       case OMPC_acquire:
6898       case OMPC_release:
6899       case OMPC_relaxed:
6900       case OMPC_depend:
6901       case OMPC_threads:
6902       case OMPC_simd:
6903       case OMPC_map:
6904       case OMPC_nogroup:
6905       case OMPC_defaultmap:
6906       case OMPC_to:
6907       case OMPC_from:
6908       case OMPC_use_device_ptr:
6909       case OMPC_use_device_addr:
6910       case OMPC_is_device_ptr:
6911       case OMPC_has_device_addr:
6912       case OMPC_nontemporal:
6913       case OMPC_order:
6914       case OMPC_destroy:
6915       case OMPC_inclusive:
6916       case OMPC_exclusive:
6917       case OMPC_uses_allocators:
6918       case OMPC_affinity:
6919       case OMPC_bind:
6920       case OMPC_filter:
6921         continue;
6922       case OMPC_allocator:
6923       case OMPC_flush:
6924       case OMPC_depobj:
6925       case OMPC_threadprivate:
6926       case OMPC_uniform:
6927       case OMPC_unknown:
6928       case OMPC_unified_address:
6929       case OMPC_unified_shared_memory:
6930       case OMPC_reverse_offload:
6931       case OMPC_dynamic_allocators:
6932       case OMPC_atomic_default_mem_order:
6933       case OMPC_device_type:
6934       case OMPC_match:
6935       case OMPC_when:
6936       case OMPC_at:
6937       case OMPC_severity:
6938       case OMPC_message:
6939       default:
6940         llvm_unreachable("Unexpected clause");
6941       }
6942       for (Stmt *CC : C->children()) {
6943         if (CC)
6944           DSAChecker.Visit(CC);
6945       }
6946     }
6947     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6948       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6949   }
6950   for (const auto &P : VarsWithInheritedDSA) {
6951     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6952       continue;
6953     ErrorFound = true;
6954     if (DSAStack->getDefaultDSA() == DSA_none ||
6955         DSAStack->getDefaultDSA() == DSA_private ||
6956         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6957       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6958           << P.first << P.second->getSourceRange();
6959       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6960     } else if (getLangOpts().OpenMP >= 50) {
6961       Diag(P.second->getExprLoc(),
6962            diag::err_omp_defaultmap_no_attr_for_variable)
6963           << P.first << P.second->getSourceRange();
6964       Diag(DSAStack->getDefaultDSALocation(),
6965            diag::note_omp_defaultmap_attr_none);
6966     }
6967   }
6968 
6969   if (!AllowedNameModifiers.empty())
6970     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6971                  ErrorFound;
6972 
6973   if (ErrorFound)
6974     return StmtError();
6975 
6976   if (!CurContext->isDependentContext() &&
6977       isOpenMPTargetExecutionDirective(Kind) &&
6978       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6979         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6980         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6981         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6982     // Register target to DSA Stack.
6983     DSAStack->addTargetDirLocation(StartLoc);
6984   }
6985 
6986   return Res;
6987 }
6988 
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)6989 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6990     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6991     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6992     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6993     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6994   assert(Aligneds.size() == Alignments.size());
6995   assert(Linears.size() == LinModifiers.size());
6996   assert(Linears.size() == Steps.size());
6997   if (!DG || DG.get().isNull())
6998     return DeclGroupPtrTy();
6999 
7000   const int SimdId = 0;
7001   if (!DG.get().isSingleDecl()) {
7002     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7003         << SimdId;
7004     return DG;
7005   }
7006   Decl *ADecl = DG.get().getSingleDecl();
7007   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7008     ADecl = FTD->getTemplatedDecl();
7009 
7010   auto *FD = dyn_cast<FunctionDecl>(ADecl);
7011   if (!FD) {
7012     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
7013     return DeclGroupPtrTy();
7014   }
7015 
7016   // OpenMP [2.8.2, declare simd construct, Description]
7017   // The parameter of the simdlen clause must be a constant positive integer
7018   // expression.
7019   ExprResult SL;
7020   if (Simdlen)
7021     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
7022   // OpenMP [2.8.2, declare simd construct, Description]
7023   // The special this pointer can be used as if was one of the arguments to the
7024   // function in any of the linear, aligned, or uniform clauses.
7025   // The uniform clause declares one or more arguments to have an invariant
7026   // value for all concurrent invocations of the function in the execution of a
7027   // single SIMD loop.
7028   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7029   const Expr *UniformedLinearThis = nullptr;
7030   for (const Expr *E : Uniforms) {
7031     E = E->IgnoreParenImpCasts();
7032     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7033       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7034         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7035             FD->getParamDecl(PVD->getFunctionScopeIndex())
7036                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
7037           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7038           continue;
7039         }
7040     if (isa<CXXThisExpr>(E)) {
7041       UniformedLinearThis = E;
7042       continue;
7043     }
7044     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7045         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7046   }
7047   // OpenMP [2.8.2, declare simd construct, Description]
7048   // The aligned clause declares that the object to which each list item points
7049   // is aligned to the number of bytes expressed in the optional parameter of
7050   // the aligned clause.
7051   // The special this pointer can be used as if was one of the arguments to the
7052   // function in any of the linear, aligned, or uniform clauses.
7053   // The type of list items appearing in the aligned clause must be array,
7054   // pointer, reference to array, or reference to pointer.
7055   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7056   const Expr *AlignedThis = nullptr;
7057   for (const Expr *E : Aligneds) {
7058     E = E->IgnoreParenImpCasts();
7059     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7060       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7061         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7062         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7063             FD->getParamDecl(PVD->getFunctionScopeIndex())
7064                     ->getCanonicalDecl() == CanonPVD) {
7065           // OpenMP  [2.8.1, simd construct, Restrictions]
7066           // A list-item cannot appear in more than one aligned clause.
7067           if (AlignedArgs.count(CanonPVD) > 0) {
7068             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7069                 << 1 << getOpenMPClauseName(OMPC_aligned)
7070                 << E->getSourceRange();
7071             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7072                  diag::note_omp_explicit_dsa)
7073                 << getOpenMPClauseName(OMPC_aligned);
7074             continue;
7075           }
7076           AlignedArgs[CanonPVD] = E;
7077           QualType QTy = PVD->getType()
7078                              .getNonReferenceType()
7079                              .getUnqualifiedType()
7080                              .getCanonicalType();
7081           const Type *Ty = QTy.getTypePtrOrNull();
7082           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
7083             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7084                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
7085             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7086           }
7087           continue;
7088         }
7089       }
7090     if (isa<CXXThisExpr>(E)) {
7091       if (AlignedThis) {
7092         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7093             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
7094         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
7095             << getOpenMPClauseName(OMPC_aligned);
7096       }
7097       AlignedThis = E;
7098       continue;
7099     }
7100     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7101         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7102   }
7103   // The optional parameter of the aligned clause, alignment, must be a constant
7104   // positive integer expression. If no optional parameter is specified,
7105   // implementation-defined default alignments for SIMD instructions on the
7106   // target platforms are assumed.
7107   SmallVector<const Expr *, 4> NewAligns;
7108   for (Expr *E : Alignments) {
7109     ExprResult Align;
7110     if (E)
7111       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
7112     NewAligns.push_back(Align.get());
7113   }
7114   // OpenMP [2.8.2, declare simd construct, Description]
7115   // The linear clause declares one or more list items to be private to a SIMD
7116   // lane and to have a linear relationship with respect to the iteration space
7117   // of a loop.
7118   // The special this pointer can be used as if was one of the arguments to the
7119   // function in any of the linear, aligned, or uniform clauses.
7120   // When a linear-step expression is specified in a linear clause it must be
7121   // either a constant integer expression or an integer-typed parameter that is
7122   // specified in a uniform clause on the directive.
7123   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7124   const bool IsUniformedThis = UniformedLinearThis != nullptr;
7125   auto MI = LinModifiers.begin();
7126   for (const Expr *E : Linears) {
7127     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
7128     ++MI;
7129     E = E->IgnoreParenImpCasts();
7130     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7131       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7132         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7133         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7134             FD->getParamDecl(PVD->getFunctionScopeIndex())
7135                     ->getCanonicalDecl() == CanonPVD) {
7136           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
7137           // A list-item cannot appear in more than one linear clause.
7138           if (LinearArgs.count(CanonPVD) > 0) {
7139             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7140                 << getOpenMPClauseName(OMPC_linear)
7141                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
7142             Diag(LinearArgs[CanonPVD]->getExprLoc(),
7143                  diag::note_omp_explicit_dsa)
7144                 << getOpenMPClauseName(OMPC_linear);
7145             continue;
7146           }
7147           // Each argument can appear in at most one uniform or linear clause.
7148           if (UniformedArgs.count(CanonPVD) > 0) {
7149             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7150                 << getOpenMPClauseName(OMPC_linear)
7151                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
7152             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7153                  diag::note_omp_explicit_dsa)
7154                 << getOpenMPClauseName(OMPC_uniform);
7155             continue;
7156           }
7157           LinearArgs[CanonPVD] = E;
7158           if (E->isValueDependent() || E->isTypeDependent() ||
7159               E->isInstantiationDependent() ||
7160               E->containsUnexpandedParameterPack())
7161             continue;
7162           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
7163                                       PVD->getOriginalType(),
7164                                       /*IsDeclareSimd=*/true);
7165           continue;
7166         }
7167       }
7168     if (isa<CXXThisExpr>(E)) {
7169       if (UniformedLinearThis) {
7170         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7171             << getOpenMPClauseName(OMPC_linear)
7172             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7173             << E->getSourceRange();
7174         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
7175             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7176                                                    : OMPC_linear);
7177         continue;
7178       }
7179       UniformedLinearThis = E;
7180       if (E->isValueDependent() || E->isTypeDependent() ||
7181           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
7182         continue;
7183       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7184                                   E->getType(), /*IsDeclareSimd=*/true);
7185       continue;
7186     }
7187     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7188         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7189   }
7190   Expr *Step = nullptr;
7191   Expr *NewStep = nullptr;
7192   SmallVector<Expr *, 4> NewSteps;
7193   for (Expr *E : Steps) {
7194     // Skip the same step expression, it was checked already.
7195     if (Step == E || !E) {
7196       NewSteps.push_back(E ? NewStep : nullptr);
7197       continue;
7198     }
7199     Step = E;
7200     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7201       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7202         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7203         if (UniformedArgs.count(CanonPVD) == 0) {
7204           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7205               << Step->getSourceRange();
7206         } else if (E->isValueDependent() || E->isTypeDependent() ||
7207                    E->isInstantiationDependent() ||
7208                    E->containsUnexpandedParameterPack() ||
7209                    CanonPVD->getType()->hasIntegerRepresentation()) {
7210           NewSteps.push_back(Step);
7211         } else {
7212           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7213               << Step->getSourceRange();
7214         }
7215         continue;
7216       }
7217     NewStep = Step;
7218     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7219         !Step->isInstantiationDependent() &&
7220         !Step->containsUnexpandedParameterPack()) {
7221       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7222                     .get();
7223       if (NewStep)
7224         NewStep =
7225             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7226     }
7227     NewSteps.push_back(NewStep);
7228   }
7229   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7230       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7231       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7232       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7233       const_cast<Expr **>(Linears.data()), Linears.size(),
7234       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7235       NewSteps.data(), NewSteps.size(), SR);
7236   ADecl->addAttr(NewAttr);
7237   return DG;
7238 }
7239 
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)7240 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7241                          QualType NewType) {
7242   assert(NewType->isFunctionProtoType() &&
7243          "Expected function type with prototype.");
7244   assert(FD->getType()->isFunctionNoProtoType() &&
7245          "Expected function with type with no prototype.");
7246   assert(FDWithProto->getType()->isFunctionProtoType() &&
7247          "Expected function with prototype.");
7248   // Synthesize parameters with the same types.
7249   FD->setType(NewType);
7250   SmallVector<ParmVarDecl *, 16> Params;
7251   for (const ParmVarDecl *P : FDWithProto->parameters()) {
7252     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7253                                       SourceLocation(), nullptr, P->getType(),
7254                                       /*TInfo=*/nullptr, SC_None, nullptr);
7255     Param->setScopeInfo(0, Params.size());
7256     Param->setImplicit();
7257     Params.push_back(Param);
7258   }
7259 
7260   FD->setParams(Params);
7261 }
7262 
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)7263 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7264   if (D->isInvalidDecl())
7265     return;
7266   FunctionDecl *FD = nullptr;
7267   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7268     FD = UTemplDecl->getTemplatedDecl();
7269   else
7270     FD = cast<FunctionDecl>(D);
7271   assert(FD && "Expected a function declaration!");
7272 
7273   // If we are instantiating templates we do *not* apply scoped assumptions but
7274   // only global ones. We apply scoped assumption to the template definition
7275   // though.
7276   if (!inTemplateInstantiation()) {
7277     for (AssumptionAttr *AA : OMPAssumeScoped)
7278       FD->addAttr(AA);
7279   }
7280   for (AssumptionAttr *AA : OMPAssumeGlobal)
7281     FD->addAttr(AA);
7282 }
7283 
OMPDeclareVariantScope(OMPTraitInfo & TI)7284 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7285     : TI(&TI), NameSuffix(TI.getMangledName()) {}
7286 
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)7287 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7288     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7289     SmallVectorImpl<FunctionDecl *> &Bases) {
7290   if (!D.getIdentifier())
7291     return;
7292 
7293   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7294 
7295   // Template specialization is an extension, check if we do it.
7296   bool IsTemplated = !TemplateParamLists.empty();
7297   if (IsTemplated &
7298       !DVScope.TI->isExtensionActive(
7299           llvm::omp::TraitProperty::implementation_extension_allow_templates))
7300     return;
7301 
7302   IdentifierInfo *BaseII = D.getIdentifier();
7303   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7304                       LookupOrdinaryName);
7305   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7306 
7307   TypeSourceInfo *TInfo = GetTypeForDeclarator(D);
7308   QualType FType = TInfo->getType();
7309 
7310   bool IsConstexpr =
7311       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7312   bool IsConsteval =
7313       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7314 
7315   for (auto *Candidate : Lookup) {
7316     auto *CandidateDecl = Candidate->getUnderlyingDecl();
7317     FunctionDecl *UDecl = nullptr;
7318     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7319       auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7320       if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7321         UDecl = FTD->getTemplatedDecl();
7322     } else if (!IsTemplated)
7323       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7324     if (!UDecl)
7325       continue;
7326 
7327     // Don't specialize constexpr/consteval functions with
7328     // non-constexpr/consteval functions.
7329     if (UDecl->isConstexpr() && !IsConstexpr)
7330       continue;
7331     if (UDecl->isConsteval() && !IsConsteval)
7332       continue;
7333 
7334     QualType UDeclTy = UDecl->getType();
7335     if (!UDeclTy->isDependentType()) {
7336       QualType NewType = Context.mergeFunctionTypes(
7337           FType, UDeclTy, /* OfBlockPointer */ false,
7338           /* Unqualified */ false, /* AllowCXX */ true);
7339       if (NewType.isNull())
7340         continue;
7341     }
7342 
7343     // Found a base!
7344     Bases.push_back(UDecl);
7345   }
7346 
7347   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7348       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7349   // If no base was found we create a declaration that we use as base.
7350   if (Bases.empty() && UseImplicitBase) {
7351     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7352     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7353     BaseD->setImplicit(true);
7354     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7355       Bases.push_back(BaseTemplD->getTemplatedDecl());
7356     else
7357       Bases.push_back(cast<FunctionDecl>(BaseD));
7358   }
7359 
7360   std::string MangledName;
7361   MangledName += D.getIdentifier()->getName();
7362   MangledName += getOpenMPVariantManglingSeparatorStr();
7363   MangledName += DVScope.NameSuffix;
7364   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7365 
7366   VariantII.setMangledOpenMPVariantName(true);
7367   D.SetIdentifier(&VariantII, D.getBeginLoc());
7368 }
7369 
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)7370 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7371     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7372   // Do not mark function as is used to prevent its emission if this is the
7373   // only place where it is used.
7374   EnterExpressionEvaluationContext Unevaluated(
7375       *this, Sema::ExpressionEvaluationContext::Unevaluated);
7376 
7377   FunctionDecl *FD = nullptr;
7378   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7379     FD = UTemplDecl->getTemplatedDecl();
7380   else
7381     FD = cast<FunctionDecl>(D);
7382   auto *VariantFuncRef = DeclRefExpr::Create(
7383       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7384       /* RefersToEnclosingVariableOrCapture */ false,
7385       /* NameLoc */ FD->getLocation(), FD->getType(),
7386       ExprValueKind::VK_PRValue);
7387 
7388   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7389   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7390       Context, VariantFuncRef, DVScope.TI,
7391       /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7392       /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7393       /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7394   for (FunctionDecl *BaseFD : Bases)
7395     BaseFD->addAttr(OMPDeclareVariantA);
7396 }
7397 
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)7398 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7399                                  SourceLocation LParenLoc,
7400                                  MultiExprArg ArgExprs,
7401                                  SourceLocation RParenLoc, Expr *ExecConfig) {
7402   // The common case is a regular call we do not want to specialize at all. Try
7403   // to make that case fast by bailing early.
7404   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7405   if (!CE)
7406     return Call;
7407 
7408   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7409   if (!CalleeFnDecl)
7410     return Call;
7411 
7412   if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7413       CalleeFnDecl->getName().starts_with_insensitive("omp_")) {
7414     // checking for any calls inside an Order region
7415     if (Scope && Scope->isOpenMPOrderClauseScope())
7416       Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7417   }
7418 
7419   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7420     return Call;
7421 
7422   ASTContext &Context = getASTContext();
7423   std::function<void(StringRef)> DiagUnknownTrait = [this,
7424                                                      CE](StringRef ISATrait) {
7425     // TODO Track the selector locations in a way that is accessible here to
7426     // improve the diagnostic location.
7427     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7428         << ISATrait;
7429   };
7430   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7431                           getCurFunctionDecl(), DSAStack->getConstructTraits());
7432 
7433   QualType CalleeFnType = CalleeFnDecl->getType();
7434 
7435   SmallVector<Expr *, 4> Exprs;
7436   SmallVector<VariantMatchInfo, 4> VMIs;
7437   while (CalleeFnDecl) {
7438     for (OMPDeclareVariantAttr *A :
7439          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7440       Expr *VariantRef = A->getVariantFuncRef();
7441 
7442       VariantMatchInfo VMI;
7443       OMPTraitInfo &TI = A->getTraitInfo();
7444       TI.getAsVariantMatchInfo(Context, VMI);
7445       if (!isVariantApplicableInContext(VMI, OMPCtx,
7446                                         /* DeviceSetOnly */ false))
7447         continue;
7448 
7449       VMIs.push_back(VMI);
7450       Exprs.push_back(VariantRef);
7451     }
7452 
7453     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7454   }
7455 
7456   ExprResult NewCall;
7457   do {
7458     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7459     if (BestIdx < 0)
7460       return Call;
7461     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7462     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7463 
7464     {
7465       // Try to build a (member) call expression for the current best applicable
7466       // variant expression. We allow this to fail in which case we continue
7467       // with the next best variant expression. The fail case is part of the
7468       // implementation defined behavior in the OpenMP standard when it talks
7469       // about what differences in the function prototypes: "Any differences
7470       // that the specific OpenMP context requires in the prototype of the
7471       // variant from the base function prototype are implementation defined."
7472       // This wording is there to allow the specialized variant to have a
7473       // different type than the base function. This is intended and OK but if
7474       // we cannot create a call the difference is not in the "implementation
7475       // defined range" we allow.
7476       Sema::TentativeAnalysisScope Trap(*this);
7477 
7478       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7479         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7480         BestExpr = MemberExpr::CreateImplicit(
7481             Context, MemberCall->getImplicitObjectArgument(),
7482             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7483             MemberCall->getValueKind(), MemberCall->getObjectKind());
7484       }
7485       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7486                               ExecConfig);
7487       if (NewCall.isUsable()) {
7488         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7489           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7490           QualType NewType = Context.mergeFunctionTypes(
7491               CalleeFnType, NewCalleeFnDecl->getType(),
7492               /* OfBlockPointer */ false,
7493               /* Unqualified */ false, /* AllowCXX */ true);
7494           if (!NewType.isNull())
7495             break;
7496           // Don't use the call if the function type was not compatible.
7497           NewCall = nullptr;
7498         }
7499       }
7500     }
7501 
7502     VMIs.erase(VMIs.begin() + BestIdx);
7503     Exprs.erase(Exprs.begin() + BestIdx);
7504   } while (!VMIs.empty());
7505 
7506   if (!NewCall.isUsable())
7507     return Call;
7508   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7509 }
7510 
7511 std::optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,unsigned NumAppendArgs,SourceRange SR)7512 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7513                                         Expr *VariantRef, OMPTraitInfo &TI,
7514                                         unsigned NumAppendArgs,
7515                                         SourceRange SR) {
7516   if (!DG || DG.get().isNull())
7517     return std::nullopt;
7518 
7519   const int VariantId = 1;
7520   // Must be applied only to single decl.
7521   if (!DG.get().isSingleDecl()) {
7522     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7523         << VariantId << SR;
7524     return std::nullopt;
7525   }
7526   Decl *ADecl = DG.get().getSingleDecl();
7527   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7528     ADecl = FTD->getTemplatedDecl();
7529 
7530   // Decl must be a function.
7531   auto *FD = dyn_cast<FunctionDecl>(ADecl);
7532   if (!FD) {
7533     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7534         << VariantId << SR;
7535     return std::nullopt;
7536   }
7537 
7538   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7539     // The 'target' attribute needs to be separately checked because it does
7540     // not always signify a multiversion function declaration.
7541     return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7542   };
7543   // OpenMP is not compatible with multiversion function attributes.
7544   if (HasMultiVersionAttributes(FD)) {
7545     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7546         << SR;
7547     return std::nullopt;
7548   }
7549 
7550   // Allow #pragma omp declare variant only if the function is not used.
7551   if (FD->isUsed(false))
7552     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7553         << FD->getLocation();
7554 
7555   // Check if the function was emitted already.
7556   const FunctionDecl *Definition;
7557   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7558       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7559     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7560         << FD->getLocation();
7561 
7562   // The VariantRef must point to function.
7563   if (!VariantRef) {
7564     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7565     return std::nullopt;
7566   }
7567 
7568   auto ShouldDelayChecks = [](Expr *&E, bool) {
7569     return E && (E->isTypeDependent() || E->isValueDependent() ||
7570                  E->containsUnexpandedParameterPack() ||
7571                  E->isInstantiationDependent());
7572   };
7573   // Do not check templates, wait until instantiation.
7574   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7575       TI.anyScoreOrCondition(ShouldDelayChecks))
7576     return std::make_pair(FD, VariantRef);
7577 
7578   // Deal with non-constant score and user condition expressions.
7579   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7580                                                      bool IsScore) -> bool {
7581     if (!E || E->isIntegerConstantExpr(Context))
7582       return false;
7583 
7584     if (IsScore) {
7585       // We warn on non-constant scores and pretend they were not present.
7586       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7587           << E;
7588       E = nullptr;
7589     } else {
7590       // We could replace a non-constant user condition with "false" but we
7591       // will soon need to handle these anyway for the dynamic version of
7592       // OpenMP context selectors.
7593       Diag(E->getExprLoc(),
7594            diag::err_omp_declare_variant_user_condition_not_constant)
7595           << E;
7596     }
7597     return true;
7598   };
7599   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7600     return std::nullopt;
7601 
7602   QualType AdjustedFnType = FD->getType();
7603   if (NumAppendArgs) {
7604     const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7605     if (!PTy) {
7606       Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7607           << SR;
7608       return std::nullopt;
7609     }
7610     // Adjust the function type to account for an extra omp_interop_t for each
7611     // specified in the append_args clause.
7612     const TypeDecl *TD = nullptr;
7613     LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7614                         SR.getBegin(), Sema::LookupOrdinaryName);
7615     if (LookupName(Result, getCurScope())) {
7616       NamedDecl *ND = Result.getFoundDecl();
7617       TD = dyn_cast_or_null<TypeDecl>(ND);
7618     }
7619     if (!TD) {
7620       Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7621       return std::nullopt;
7622     }
7623     QualType InteropType = Context.getTypeDeclType(TD);
7624     if (PTy->isVariadic()) {
7625       Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7626       return std::nullopt;
7627     }
7628     llvm::SmallVector<QualType, 8> Params;
7629     Params.append(PTy->param_type_begin(), PTy->param_type_end());
7630     Params.insert(Params.end(), NumAppendArgs, InteropType);
7631     AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7632                                              PTy->getExtProtoInfo());
7633   }
7634 
7635   // Convert VariantRef expression to the type of the original function to
7636   // resolve possible conflicts.
7637   ExprResult VariantRefCast = VariantRef;
7638   if (LangOpts.CPlusPlus) {
7639     QualType FnPtrType;
7640     auto *Method = dyn_cast<CXXMethodDecl>(FD);
7641     if (Method && !Method->isStatic()) {
7642       const Type *ClassType =
7643           Context.getTypeDeclType(Method->getParent()).getTypePtr();
7644       FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7645       ExprResult ER;
7646       {
7647         // Build adrr_of unary op to correctly handle type checks for member
7648         // functions.
7649         Sema::TentativeAnalysisScope Trap(*this);
7650         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7651                                   VariantRef);
7652       }
7653       if (!ER.isUsable()) {
7654         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7655             << VariantId << VariantRef->getSourceRange();
7656         return std::nullopt;
7657       }
7658       VariantRef = ER.get();
7659     } else {
7660       FnPtrType = Context.getPointerType(AdjustedFnType);
7661     }
7662     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7663     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7664       ImplicitConversionSequence ICS = TryImplicitConversion(
7665           VariantRef, FnPtrType.getUnqualifiedType(),
7666           /*SuppressUserConversions=*/false, AllowedExplicit::None,
7667           /*InOverloadResolution=*/false,
7668           /*CStyle=*/false,
7669           /*AllowObjCWritebackConversion=*/false);
7670       if (ICS.isFailure()) {
7671         Diag(VariantRef->getExprLoc(),
7672              diag::err_omp_declare_variant_incompat_types)
7673             << VariantRef->getType()
7674             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7675             << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7676         return std::nullopt;
7677       }
7678       VariantRefCast = PerformImplicitConversion(
7679           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7680       if (!VariantRefCast.isUsable())
7681         return std::nullopt;
7682     }
7683     // Drop previously built artificial addr_of unary op for member functions.
7684     if (Method && !Method->isStatic()) {
7685       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7686       if (auto *UO = dyn_cast<UnaryOperator>(
7687               PossibleAddrOfVariantRef->IgnoreImplicit()))
7688         VariantRefCast = UO->getSubExpr();
7689     }
7690   }
7691 
7692   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7693   if (!ER.isUsable() ||
7694       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7695     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7696         << VariantId << VariantRef->getSourceRange();
7697     return std::nullopt;
7698   }
7699 
7700   // The VariantRef must point to function.
7701   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7702   if (!DRE) {
7703     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7704         << VariantId << VariantRef->getSourceRange();
7705     return std::nullopt;
7706   }
7707   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7708   if (!NewFD) {
7709     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7710         << VariantId << VariantRef->getSourceRange();
7711     return std::nullopt;
7712   }
7713 
7714   if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7715     Diag(VariantRef->getExprLoc(),
7716          diag::err_omp_declare_variant_same_base_function)
7717         << VariantRef->getSourceRange();
7718     return std::nullopt;
7719   }
7720 
7721   // Check if function types are compatible in C.
7722   if (!LangOpts.CPlusPlus) {
7723     QualType NewType =
7724         Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7725     if (NewType.isNull()) {
7726       Diag(VariantRef->getExprLoc(),
7727            diag::err_omp_declare_variant_incompat_types)
7728           << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7729           << VariantRef->getSourceRange();
7730       return std::nullopt;
7731     }
7732     if (NewType->isFunctionProtoType()) {
7733       if (FD->getType()->isFunctionNoProtoType())
7734         setPrototype(*this, FD, NewFD, NewType);
7735       else if (NewFD->getType()->isFunctionNoProtoType())
7736         setPrototype(*this, NewFD, FD, NewType);
7737     }
7738   }
7739 
7740   // Check if variant function is not marked with declare variant directive.
7741   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7742     Diag(VariantRef->getExprLoc(),
7743          diag::warn_omp_declare_variant_marked_as_declare_variant)
7744         << VariantRef->getSourceRange();
7745     SourceRange SR =
7746         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7747     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7748     return std::nullopt;
7749   }
7750 
7751   enum DoesntSupport {
7752     VirtFuncs = 1,
7753     Constructors = 3,
7754     Destructors = 4,
7755     DeletedFuncs = 5,
7756     DefaultedFuncs = 6,
7757     ConstexprFuncs = 7,
7758     ConstevalFuncs = 8,
7759   };
7760   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7761     if (CXXFD->isVirtual()) {
7762       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7763           << VirtFuncs;
7764       return std::nullopt;
7765     }
7766 
7767     if (isa<CXXConstructorDecl>(FD)) {
7768       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7769           << Constructors;
7770       return std::nullopt;
7771     }
7772 
7773     if (isa<CXXDestructorDecl>(FD)) {
7774       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7775           << Destructors;
7776       return std::nullopt;
7777     }
7778   }
7779 
7780   if (FD->isDeleted()) {
7781     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7782         << DeletedFuncs;
7783     return std::nullopt;
7784   }
7785 
7786   if (FD->isDefaulted()) {
7787     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7788         << DefaultedFuncs;
7789     return std::nullopt;
7790   }
7791 
7792   if (FD->isConstexpr()) {
7793     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7794         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7795     return std::nullopt;
7796   }
7797 
7798   // Check general compatibility.
7799   if (areMultiversionVariantFunctionsCompatible(
7800           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7801           PartialDiagnosticAt(SourceLocation(),
7802                               PartialDiagnostic::NullDiagnostic()),
7803           PartialDiagnosticAt(
7804               VariantRef->getExprLoc(),
7805               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7806           PartialDiagnosticAt(VariantRef->getExprLoc(),
7807                               PDiag(diag::err_omp_declare_variant_diff)
7808                                   << FD->getLocation()),
7809           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7810           /*CLinkageMayDiffer=*/true))
7811     return std::nullopt;
7812   return std::make_pair(FD, cast<Expr>(DRE));
7813 }
7814 
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,ArrayRef<Expr * > AdjustArgsNothing,ArrayRef<Expr * > AdjustArgsNeedDevicePtr,ArrayRef<OMPInteropInfo> AppendArgs,SourceLocation AdjustArgsLoc,SourceLocation AppendArgsLoc,SourceRange SR)7815 void Sema::ActOnOpenMPDeclareVariantDirective(
7816     FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7817     ArrayRef<Expr *> AdjustArgsNothing,
7818     ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7819     ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7820     SourceLocation AppendArgsLoc, SourceRange SR) {
7821 
7822   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7823   // An adjust_args clause or append_args clause can only be specified if the
7824   // dispatch selector of the construct selector set appears in the match
7825   // clause.
7826 
7827   SmallVector<Expr *, 8> AllAdjustArgs;
7828   llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7829   llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7830 
7831   if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7832     VariantMatchInfo VMI;
7833     TI.getAsVariantMatchInfo(Context, VMI);
7834     if (!llvm::is_contained(
7835             VMI.ConstructTraits,
7836             llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7837       if (!AllAdjustArgs.empty())
7838         Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7839             << getOpenMPClauseName(OMPC_adjust_args);
7840       if (!AppendArgs.empty())
7841         Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7842             << getOpenMPClauseName(OMPC_append_args);
7843       return;
7844     }
7845   }
7846 
7847   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7848   // Each argument can only appear in a single adjust_args clause for each
7849   // declare variant directive.
7850   llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7851 
7852   for (Expr *E : AllAdjustArgs) {
7853     E = E->IgnoreParenImpCasts();
7854     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7855       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7856         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7857         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7858             FD->getParamDecl(PVD->getFunctionScopeIndex())
7859                     ->getCanonicalDecl() == CanonPVD) {
7860           // It's a parameter of the function, check duplicates.
7861           if (!AdjustVars.insert(CanonPVD).second) {
7862             Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7863                 << PVD;
7864             return;
7865           }
7866           continue;
7867         }
7868       }
7869     }
7870     // Anything that is not a function parameter is an error.
7871     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7872     return;
7873   }
7874 
7875   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7876       Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7877       AdjustArgsNothing.size(),
7878       const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7879       AdjustArgsNeedDevicePtr.size(),
7880       const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7881   FD->addAttr(NewAttr);
7882 }
7883 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7884 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7885                                               Stmt *AStmt,
7886                                               SourceLocation StartLoc,
7887                                               SourceLocation EndLoc) {
7888   if (!AStmt)
7889     return StmtError();
7890 
7891   auto *CS = cast<CapturedStmt>(AStmt);
7892   // 1.2.2 OpenMP Language Terminology
7893   // Structured block - An executable statement with a single entry at the
7894   // top and a single exit at the bottom.
7895   // The point of exit cannot be a branch out of the structured block.
7896   // longjmp() and throw() must not violate the entry/exit criteria.
7897   CS->getCapturedDecl()->setNothrow();
7898 
7899   setFunctionHasBranchProtectedScope();
7900 
7901   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7902                                       DSAStack->getTaskgroupReductionRef(),
7903                                       DSAStack->isCancelRegion());
7904 }
7905 
7906 namespace {
7907 /// Iteration space of a single for loop.
7908 struct LoopIterationSpace final {
7909   /// True if the condition operator is the strict compare operator (<, > or
7910   /// !=).
7911   bool IsStrictCompare = false;
7912   /// Condition of the loop.
7913   Expr *PreCond = nullptr;
7914   /// This expression calculates the number of iterations in the loop.
7915   /// It is always possible to calculate it before starting the loop.
7916   Expr *NumIterations = nullptr;
7917   /// The loop counter variable.
7918   Expr *CounterVar = nullptr;
7919   /// Private loop counter variable.
7920   Expr *PrivateCounterVar = nullptr;
7921   /// This is initializer for the initial value of #CounterVar.
7922   Expr *CounterInit = nullptr;
7923   /// This is step for the #CounterVar used to generate its update:
7924   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7925   Expr *CounterStep = nullptr;
7926   /// Should step be subtracted?
7927   bool Subtract = false;
7928   /// Source range of the loop init.
7929   SourceRange InitSrcRange;
7930   /// Source range of the loop condition.
7931   SourceRange CondSrcRange;
7932   /// Source range of the loop increment.
7933   SourceRange IncSrcRange;
7934   /// Minimum value that can have the loop control variable. Used to support
7935   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7936   /// since only such variables can be used in non-loop invariant expressions.
7937   Expr *MinValue = nullptr;
7938   /// Maximum value that can have the loop control variable. Used to support
7939   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7940   /// since only such variables can be used in non-loop invariant expressions.
7941   Expr *MaxValue = nullptr;
7942   /// true, if the lower bound depends on the outer loop control var.
7943   bool IsNonRectangularLB = false;
7944   /// true, if the upper bound depends on the outer loop control var.
7945   bool IsNonRectangularUB = false;
7946   /// Index of the loop this loop depends on and forms non-rectangular loop
7947   /// nest.
7948   unsigned LoopDependentIdx = 0;
7949   /// Final condition for the non-rectangular loop nest support. It is used to
7950   /// check that the number of iterations for this particular counter must be
7951   /// finished.
7952   Expr *FinalCondition = nullptr;
7953 };
7954 
7955 /// Helper class for checking canonical form of the OpenMP loops and
7956 /// extracting iteration space of each loop in the loop nest, that will be used
7957 /// for IR generation.
7958 class OpenMPIterationSpaceChecker {
7959   /// Reference to Sema.
7960   Sema &SemaRef;
7961   /// Does the loop associated directive support non-rectangular loops?
7962   bool SupportsNonRectangular;
7963   /// Data-sharing stack.
7964   DSAStackTy &Stack;
7965   /// A location for diagnostics (when there is no some better location).
7966   SourceLocation DefaultLoc;
7967   /// A location for diagnostics (when increment is not compatible).
7968   SourceLocation ConditionLoc;
7969   /// A source location for referring to loop init later.
7970   SourceRange InitSrcRange;
7971   /// A source location for referring to condition later.
7972   SourceRange ConditionSrcRange;
7973   /// A source location for referring to increment later.
7974   SourceRange IncrementSrcRange;
7975   /// Loop variable.
7976   ValueDecl *LCDecl = nullptr;
7977   /// Reference to loop variable.
7978   Expr *LCRef = nullptr;
7979   /// Lower bound (initializer for the var).
7980   Expr *LB = nullptr;
7981   /// Upper bound.
7982   Expr *UB = nullptr;
7983   /// Loop step (increment).
7984   Expr *Step = nullptr;
7985   /// This flag is true when condition is one of:
7986   ///   Var <  UB
7987   ///   Var <= UB
7988   ///   UB  >  Var
7989   ///   UB  >= Var
7990   /// This will have no value when the condition is !=
7991   std::optional<bool> TestIsLessOp;
7992   /// This flag is true when condition is strict ( < or > ).
7993   bool TestIsStrictOp = false;
7994   /// This flag is true when step is subtracted on each iteration.
7995   bool SubtractStep = false;
7996   /// The outer loop counter this loop depends on (if any).
7997   const ValueDecl *DepDecl = nullptr;
7998   /// Contains number of loop (starts from 1) on which loop counter init
7999   /// expression of this loop depends on.
8000   std::optional<unsigned> InitDependOnLC;
8001   /// Contains number of loop (starts from 1) on which loop counter condition
8002   /// expression of this loop depends on.
8003   std::optional<unsigned> CondDependOnLC;
8004   /// Checks if the provide statement depends on the loop counter.
8005   std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
8006                                                   bool IsInitializer);
8007   /// Original condition required for checking of the exit condition for
8008   /// non-rectangular loop.
8009   Expr *Condition = nullptr;
8010 
8011 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,bool SupportsNonRectangular,DSAStackTy & Stack,SourceLocation DefaultLoc)8012   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
8013                               DSAStackTy &Stack, SourceLocation DefaultLoc)
8014       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
8015         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
8016   /// Check init-expr for canonical loop form and save loop counter
8017   /// variable - #Var and its initialization value - #LB.
8018   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
8019   /// Check test-expr for canonical form, save upper-bound (#UB), flags
8020   /// for less/greater and for strict/non-strict comparison.
8021   bool checkAndSetCond(Expr *S);
8022   /// Check incr-expr for canonical loop form and return true if it
8023   /// does not conform, otherwise save loop step (#Step).
8024   bool checkAndSetInc(Expr *S);
8025   /// Return the loop counter variable.
getLoopDecl() const8026   ValueDecl *getLoopDecl() const { return LCDecl; }
8027   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const8028   Expr *getLoopDeclRefExpr() const { return LCRef; }
8029   /// Source range of the loop init.
getInitSrcRange() const8030   SourceRange getInitSrcRange() const { return InitSrcRange; }
8031   /// Source range of the loop condition.
getConditionSrcRange() const8032   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
8033   /// Source range of the loop increment.
getIncrementSrcRange() const8034   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
8035   /// True if the step should be subtracted.
shouldSubtractStep() const8036   bool shouldSubtractStep() const { return SubtractStep; }
8037   /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const8038   bool isStrictTestOp() const { return TestIsStrictOp; }
8039   /// Build the expression to calculate the number of iterations.
8040   Expr *buildNumIterations(
8041       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8042       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8043   /// Build the precondition expression for the loops.
8044   Expr *
8045   buildPreCond(Scope *S, Expr *Cond,
8046                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8047   /// Build reference expression to the counter be used for codegen.
8048   DeclRefExpr *
8049   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8050                   DSAStackTy &DSA) const;
8051   /// Build reference expression to the private counter be used for
8052   /// codegen.
8053   Expr *buildPrivateCounterVar() const;
8054   /// Build initialization of the counter be used for codegen.
8055   Expr *buildCounterInit() const;
8056   /// Build step of the counter be used for codegen.
8057   Expr *buildCounterStep() const;
8058   /// Build loop data with counter value for depend clauses in ordered
8059   /// directives.
8060   Expr *
8061   buildOrderedLoopData(Scope *S, Expr *Counter,
8062                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8063                        SourceLocation Loc, Expr *Inc = nullptr,
8064                        OverloadedOperatorKind OOK = OO_Amp);
8065   /// Builds the minimum value for the loop counter.
8066   std::pair<Expr *, Expr *> buildMinMaxValues(
8067       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8068   /// Builds final condition for the non-rectangular loops.
8069   Expr *buildFinalCondition(Scope *S) const;
8070   /// Return true if any expression is dependent.
8071   bool dependent() const;
8072   /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const8073   bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
8074   /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const8075   bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
8076   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const8077   unsigned getLoopDependentIdx() const {
8078     return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8079   }
8080 
8081 private:
8082   /// Check the right-hand side of an assignment in the increment
8083   /// expression.
8084   bool checkAndSetIncRHS(Expr *RHS);
8085   /// Helper to set loop counter variable and its initializer.
8086   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
8087                       bool EmitDiags);
8088   /// Helper to set upper bound.
8089   bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
8090              SourceRange SR, SourceLocation SL);
8091   /// Helper to set loop increment.
8092   bool setStep(Expr *NewStep, bool Subtract);
8093 };
8094 
dependent() const8095 bool OpenMPIterationSpaceChecker::dependent() const {
8096   if (!LCDecl) {
8097     assert(!LB && !UB && !Step);
8098     return false;
8099   }
8100   return LCDecl->getType()->isDependentType() ||
8101          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
8102          (Step && Step->isValueDependent());
8103 }
8104 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)8105 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
8106                                                  Expr *NewLCRefExpr,
8107                                                  Expr *NewLB, bool EmitDiags) {
8108   // State consistency checking to ensure correct usage.
8109   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
8110          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8111   if (!NewLCDecl || !NewLB || NewLB->containsErrors())
8112     return true;
8113   LCDecl = getCanonicalDecl(NewLCDecl);
8114   LCRef = NewLCRefExpr;
8115   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8116     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8117       if ((Ctor->isCopyOrMoveConstructor() ||
8118            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8119           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8120         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
8121   LB = NewLB;
8122   if (EmitDiags)
8123     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
8124   return false;
8125 }
8126 
setUB(Expr * NewUB,std::optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)8127 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
8128                                         bool StrictOp, SourceRange SR,
8129                                         SourceLocation SL) {
8130   // State consistency checking to ensure correct usage.
8131   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
8132          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8133   if (!NewUB || NewUB->containsErrors())
8134     return true;
8135   UB = NewUB;
8136   if (LessOp)
8137     TestIsLessOp = LessOp;
8138   TestIsStrictOp = StrictOp;
8139   ConditionSrcRange = SR;
8140   ConditionLoc = SL;
8141   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
8142   return false;
8143 }
8144 
setStep(Expr * NewStep,bool Subtract)8145 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
8146   // State consistency checking to ensure correct usage.
8147   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
8148   if (!NewStep || NewStep->containsErrors())
8149     return true;
8150   if (!NewStep->isValueDependent()) {
8151     // Check that the step is integer expression.
8152     SourceLocation StepLoc = NewStep->getBeginLoc();
8153     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
8154         StepLoc, getExprAsWritten(NewStep));
8155     if (Val.isInvalid())
8156       return true;
8157     NewStep = Val.get();
8158 
8159     // OpenMP [2.6, Canonical Loop Form, Restrictions]
8160     //  If test-expr is of form var relational-op b and relational-op is < or
8161     //  <= then incr-expr must cause var to increase on each iteration of the
8162     //  loop. If test-expr is of form var relational-op b and relational-op is
8163     //  > or >= then incr-expr must cause var to decrease on each iteration of
8164     //  the loop.
8165     //  If test-expr is of form b relational-op var and relational-op is < or
8166     //  <= then incr-expr must cause var to decrease on each iteration of the
8167     //  loop. If test-expr is of form b relational-op var and relational-op is
8168     //  > or >= then incr-expr must cause var to increase on each iteration of
8169     //  the loop.
8170     std::optional<llvm::APSInt> Result =
8171         NewStep->getIntegerConstantExpr(SemaRef.Context);
8172     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
8173     bool IsConstNeg =
8174         Result && Result->isSigned() && (Subtract != Result->isNegative());
8175     bool IsConstPos =
8176         Result && Result->isSigned() && (Subtract == Result->isNegative());
8177     bool IsConstZero = Result && !Result->getBoolValue();
8178 
8179     // != with increment is treated as <; != with decrement is treated as >
8180     if (!TestIsLessOp)
8181       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8182     if (UB && (IsConstZero ||
8183                (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8184                               : (IsConstPos || (IsUnsigned && !Subtract))))) {
8185       SemaRef.Diag(NewStep->getExprLoc(),
8186                    diag::err_omp_loop_incr_not_compatible)
8187           << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8188       SemaRef.Diag(ConditionLoc,
8189                    diag::note_omp_loop_cond_requres_compatible_incr)
8190           << *TestIsLessOp << ConditionSrcRange;
8191       return true;
8192     }
8193     if (*TestIsLessOp == Subtract) {
8194       NewStep =
8195           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8196               .get();
8197       Subtract = !Subtract;
8198     }
8199   }
8200 
8201   Step = NewStep;
8202   SubtractStep = Subtract;
8203   return false;
8204 }
8205 
8206 namespace {
8207 /// Checker for the non-rectangular loops. Checks if the initializer or
8208 /// condition expression references loop counter variable.
8209 class LoopCounterRefChecker final
8210     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8211   Sema &SemaRef;
8212   DSAStackTy &Stack;
8213   const ValueDecl *CurLCDecl = nullptr;
8214   const ValueDecl *DepDecl = nullptr;
8215   const ValueDecl *PrevDepDecl = nullptr;
8216   bool IsInitializer = true;
8217   bool SupportsNonRectangular;
8218   unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)8219   bool checkDecl(const Expr *E, const ValueDecl *VD) {
8220     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8221       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8222           << (IsInitializer ? 0 : 1);
8223       return false;
8224     }
8225     const auto &&Data = Stack.isLoopControlVariable(VD);
8226     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8227     // The type of the loop iterator on which we depend may not have a random
8228     // access iterator type.
8229     if (Data.first && VD->getType()->isRecordType()) {
8230       SmallString<128> Name;
8231       llvm::raw_svector_ostream OS(Name);
8232       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8233                                /*Qualified=*/true);
8234       SemaRef.Diag(E->getExprLoc(),
8235                    diag::err_omp_wrong_dependency_iterator_type)
8236           << OS.str();
8237       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8238       return false;
8239     }
8240     if (Data.first && !SupportsNonRectangular) {
8241       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8242       return false;
8243     }
8244     if (Data.first &&
8245         (DepDecl || (PrevDepDecl &&
8246                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8247       if (!DepDecl && PrevDepDecl)
8248         DepDecl = PrevDepDecl;
8249       SmallString<128> Name;
8250       llvm::raw_svector_ostream OS(Name);
8251       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8252                                     /*Qualified=*/true);
8253       SemaRef.Diag(E->getExprLoc(),
8254                    diag::err_omp_invariant_or_linear_dependency)
8255           << OS.str();
8256       return false;
8257     }
8258     if (Data.first) {
8259       DepDecl = VD;
8260       BaseLoopId = Data.first;
8261     }
8262     return Data.first;
8263   }
8264 
8265 public:
VisitDeclRefExpr(const DeclRefExpr * E)8266   bool VisitDeclRefExpr(const DeclRefExpr *E) {
8267     const ValueDecl *VD = E->getDecl();
8268     if (isa<VarDecl>(VD))
8269       return checkDecl(E, VD);
8270     return false;
8271   }
VisitMemberExpr(const MemberExpr * E)8272   bool VisitMemberExpr(const MemberExpr *E) {
8273     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8274       const ValueDecl *VD = E->getMemberDecl();
8275       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8276         return checkDecl(E, VD);
8277     }
8278     return false;
8279   }
VisitStmt(const Stmt * S)8280   bool VisitStmt(const Stmt *S) {
8281     bool Res = false;
8282     for (const Stmt *Child : S->children())
8283       Res = (Child && Visit(Child)) || Res;
8284     return Res;
8285   }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr,bool SupportsNonRectangular=true)8286   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8287                                  const ValueDecl *CurLCDecl, bool IsInitializer,
8288                                  const ValueDecl *PrevDepDecl = nullptr,
8289                                  bool SupportsNonRectangular = true)
8290       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8291         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8292         SupportsNonRectangular(SupportsNonRectangular) {}
getBaseLoopId() const8293   unsigned getBaseLoopId() const {
8294     assert(CurLCDecl && "Expected loop dependency.");
8295     return BaseLoopId;
8296   }
getDepDecl() const8297   const ValueDecl *getDepDecl() const {
8298     assert(CurLCDecl && "Expected loop dependency.");
8299     return DepDecl;
8300   }
8301 };
8302 } // namespace
8303 
8304 std::optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)8305 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8306                                                      bool IsInitializer) {
8307   // Check for the non-rectangular loops.
8308   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8309                                         DepDecl, SupportsNonRectangular);
8310   if (LoopStmtChecker.Visit(S)) {
8311     DepDecl = LoopStmtChecker.getDepDecl();
8312     return LoopStmtChecker.getBaseLoopId();
8313   }
8314   return std::nullopt;
8315 }
8316 
checkAndSetInit(Stmt * S,bool EmitDiags)8317 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8318   // Check init-expr for canonical loop form and save loop counter
8319   // variable - #Var and its initialization value - #LB.
8320   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8321   //   var = lb
8322   //   integer-type var = lb
8323   //   random-access-iterator-type var = lb
8324   //   pointer-type var = lb
8325   //
8326   if (!S) {
8327     if (EmitDiags) {
8328       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8329     }
8330     return true;
8331   }
8332   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8333     if (!ExprTemp->cleanupsHaveSideEffects())
8334       S = ExprTemp->getSubExpr();
8335 
8336   InitSrcRange = S->getSourceRange();
8337   if (Expr *E = dyn_cast<Expr>(S))
8338     S = E->IgnoreParens();
8339   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8340     if (BO->getOpcode() == BO_Assign) {
8341       Expr *LHS = BO->getLHS()->IgnoreParens();
8342       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8343         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8344           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8345             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8346                                   EmitDiags);
8347         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8348       }
8349       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8350         if (ME->isArrow() &&
8351             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8352           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8353                                 EmitDiags);
8354       }
8355     }
8356   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8357     if (DS->isSingleDecl()) {
8358       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8359         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8360           // Accept non-canonical init form here but emit ext. warning.
8361           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8362             SemaRef.Diag(S->getBeginLoc(),
8363                          diag::ext_omp_loop_not_canonical_init)
8364                 << S->getSourceRange();
8365           return setLCDeclAndLB(
8366               Var,
8367               buildDeclRefExpr(SemaRef, Var,
8368                                Var->getType().getNonReferenceType(),
8369                                DS->getBeginLoc()),
8370               Var->getInit(), EmitDiags);
8371         }
8372       }
8373     }
8374   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8375     if (CE->getOperator() == OO_Equal) {
8376       Expr *LHS = CE->getArg(0);
8377       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8378         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8379           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8380             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8381                                   EmitDiags);
8382         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8383       }
8384       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8385         if (ME->isArrow() &&
8386             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8387           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8388                                 EmitDiags);
8389       }
8390     }
8391   }
8392 
8393   if (dependent() || SemaRef.CurContext->isDependentContext())
8394     return false;
8395   if (EmitDiags) {
8396     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8397         << S->getSourceRange();
8398   }
8399   return true;
8400 }
8401 
8402 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8403 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)8404 static const ValueDecl *getInitLCDecl(const Expr *E) {
8405   if (!E)
8406     return nullptr;
8407   E = getExprAsWritten(E);
8408   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8409     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8410       if ((Ctor->isCopyOrMoveConstructor() ||
8411            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8412           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8413         E = CE->getArg(0)->IgnoreParenImpCasts();
8414   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8415     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8416       return getCanonicalDecl(VD);
8417   }
8418   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8419     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8420       return getCanonicalDecl(ME->getMemberDecl());
8421   return nullptr;
8422 }
8423 
checkAndSetCond(Expr * S)8424 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8425   // Check test-expr for canonical form, save upper-bound UB, flags for
8426   // less/greater and for strict/non-strict comparison.
8427   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8428   //   var relational-op b
8429   //   b relational-op var
8430   //
8431   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8432   if (!S) {
8433     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8434         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8435     return true;
8436   }
8437   Condition = S;
8438   S = getExprAsWritten(S);
8439   SourceLocation CondLoc = S->getBeginLoc();
8440   auto &&CheckAndSetCond =
8441       [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8442                                   const Expr *RHS, SourceRange SR,
8443                                   SourceLocation OpLoc) -> std::optional<bool> {
8444     if (BinaryOperator::isRelationalOp(Opcode)) {
8445       if (getInitLCDecl(LHS) == LCDecl)
8446         return setUB(const_cast<Expr *>(RHS),
8447                      (Opcode == BO_LT || Opcode == BO_LE),
8448                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8449       if (getInitLCDecl(RHS) == LCDecl)
8450         return setUB(const_cast<Expr *>(LHS),
8451                      (Opcode == BO_GT || Opcode == BO_GE),
8452                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8453     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8454       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8455                    /*LessOp=*/std::nullopt,
8456                    /*StrictOp=*/true, SR, OpLoc);
8457     }
8458     return std::nullopt;
8459   };
8460   std::optional<bool> Res;
8461   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8462     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8463     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8464                           RBO->getOperatorLoc());
8465   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8466     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8467                           BO->getSourceRange(), BO->getOperatorLoc());
8468   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8469     if (CE->getNumArgs() == 2) {
8470       Res = CheckAndSetCond(
8471           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8472           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8473     }
8474   }
8475   if (Res)
8476     return *Res;
8477   if (dependent() || SemaRef.CurContext->isDependentContext())
8478     return false;
8479   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8480       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8481   return true;
8482 }
8483 
checkAndSetIncRHS(Expr * RHS)8484 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8485   // RHS of canonical loop form increment can be:
8486   //   var + incr
8487   //   incr + var
8488   //   var - incr
8489   //
8490   RHS = RHS->IgnoreParenImpCasts();
8491   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8492     if (BO->isAdditiveOp()) {
8493       bool IsAdd = BO->getOpcode() == BO_Add;
8494       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8495         return setStep(BO->getRHS(), !IsAdd);
8496       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8497         return setStep(BO->getLHS(), /*Subtract=*/false);
8498     }
8499   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8500     bool IsAdd = CE->getOperator() == OO_Plus;
8501     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8502       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8503         return setStep(CE->getArg(1), !IsAdd);
8504       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8505         return setStep(CE->getArg(0), /*Subtract=*/false);
8506     }
8507   }
8508   if (dependent() || SemaRef.CurContext->isDependentContext())
8509     return false;
8510   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8511       << RHS->getSourceRange() << LCDecl;
8512   return true;
8513 }
8514 
checkAndSetInc(Expr * S)8515 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8516   // Check incr-expr for canonical loop form and return true if it
8517   // does not conform.
8518   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8519   //   ++var
8520   //   var++
8521   //   --var
8522   //   var--
8523   //   var += incr
8524   //   var -= incr
8525   //   var = var + incr
8526   //   var = incr + var
8527   //   var = var - incr
8528   //
8529   if (!S) {
8530     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8531     return true;
8532   }
8533   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8534     if (!ExprTemp->cleanupsHaveSideEffects())
8535       S = ExprTemp->getSubExpr();
8536 
8537   IncrementSrcRange = S->getSourceRange();
8538   S = S->IgnoreParens();
8539   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8540     if (UO->isIncrementDecrementOp() &&
8541         getInitLCDecl(UO->getSubExpr()) == LCDecl)
8542       return setStep(SemaRef
8543                          .ActOnIntegerConstant(UO->getBeginLoc(),
8544                                                (UO->isDecrementOp() ? -1 : 1))
8545                          .get(),
8546                      /*Subtract=*/false);
8547   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8548     switch (BO->getOpcode()) {
8549     case BO_AddAssign:
8550     case BO_SubAssign:
8551       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8552         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8553       break;
8554     case BO_Assign:
8555       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8556         return checkAndSetIncRHS(BO->getRHS());
8557       break;
8558     default:
8559       break;
8560     }
8561   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8562     switch (CE->getOperator()) {
8563     case OO_PlusPlus:
8564     case OO_MinusMinus:
8565       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8566         return setStep(SemaRef
8567                            .ActOnIntegerConstant(
8568                                CE->getBeginLoc(),
8569                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8570                            .get(),
8571                        /*Subtract=*/false);
8572       break;
8573     case OO_PlusEqual:
8574     case OO_MinusEqual:
8575       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8576         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8577       break;
8578     case OO_Equal:
8579       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8580         return checkAndSetIncRHS(CE->getArg(1));
8581       break;
8582     default:
8583       break;
8584     }
8585   }
8586   if (dependent() || SemaRef.CurContext->isDependentContext())
8587     return false;
8588   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8589       << S->getSourceRange() << LCDecl;
8590   return true;
8591 }
8592 
8593 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,StringRef Name=".capture_expr.")8594 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8595                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8596                 StringRef Name = ".capture_expr.") {
8597   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8598     return Capture;
8599   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8600     return SemaRef.PerformImplicitConversion(
8601         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8602         /*AllowExplicit=*/true);
8603   auto I = Captures.find(Capture);
8604   if (I != Captures.end())
8605     return buildCapture(SemaRef, Capture, I->second, Name);
8606   DeclRefExpr *Ref = nullptr;
8607   ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8608   Captures[Capture] = Ref;
8609   return Res;
8610 }
8611 
8612 /// Calculate number of iterations, transforming to unsigned, if number of
8613 /// iterations may be larger than the original type.
8614 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)8615 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8616                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8617                   bool TestIsStrictOp, bool RoundToStep,
8618                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8619   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8620   if (!NewStep.isUsable())
8621     return nullptr;
8622   llvm::APSInt LRes, SRes;
8623   bool IsLowerConst = false, IsStepConst = false;
8624   if (std::optional<llvm::APSInt> Res =
8625           Lower->getIntegerConstantExpr(SemaRef.Context)) {
8626     LRes = *Res;
8627     IsLowerConst = true;
8628   }
8629   if (std::optional<llvm::APSInt> Res =
8630           Step->getIntegerConstantExpr(SemaRef.Context)) {
8631     SRes = *Res;
8632     IsStepConst = true;
8633   }
8634   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8635                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
8636                           (TestIsStrictOp && LRes.isStrictlyPositive()));
8637   bool NeedToReorganize = false;
8638   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8639   if (!NoNeedToConvert && IsLowerConst &&
8640       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8641     NoNeedToConvert = true;
8642     if (RoundToStep) {
8643       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8644                         ? LRes.getBitWidth()
8645                         : SRes.getBitWidth();
8646       LRes = LRes.extend(BW + 1);
8647       LRes.setIsSigned(true);
8648       SRes = SRes.extend(BW + 1);
8649       SRes.setIsSigned(true);
8650       LRes -= SRes;
8651       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8652       LRes = LRes.trunc(BW);
8653     }
8654     if (TestIsStrictOp) {
8655       unsigned BW = LRes.getBitWidth();
8656       LRes = LRes.extend(BW + 1);
8657       LRes.setIsSigned(true);
8658       ++LRes;
8659       NoNeedToConvert =
8660           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8661       // truncate to the original bitwidth.
8662       LRes = LRes.trunc(BW);
8663     }
8664     NeedToReorganize = NoNeedToConvert;
8665   }
8666   llvm::APSInt URes;
8667   bool IsUpperConst = false;
8668   if (std::optional<llvm::APSInt> Res =
8669           Upper->getIntegerConstantExpr(SemaRef.Context)) {
8670     URes = *Res;
8671     IsUpperConst = true;
8672   }
8673   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8674       (!RoundToStep || IsStepConst)) {
8675     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8676                                                           : URes.getBitWidth();
8677     LRes = LRes.extend(BW + 1);
8678     LRes.setIsSigned(true);
8679     URes = URes.extend(BW + 1);
8680     URes.setIsSigned(true);
8681     URes -= LRes;
8682     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8683     NeedToReorganize = NoNeedToConvert;
8684   }
8685   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8686   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8687   // unsigned.
8688   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8689       !LCTy->isDependentType() && LCTy->isIntegerType()) {
8690     QualType LowerTy = Lower->getType();
8691     QualType UpperTy = Upper->getType();
8692     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8693     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8694     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8695         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8696       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8697           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8698       Upper =
8699           SemaRef
8700               .PerformImplicitConversion(
8701                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8702                   CastType, Sema::AA_Converting)
8703               .get();
8704       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8705       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8706     }
8707   }
8708   if (!Lower || !Upper || NewStep.isInvalid())
8709     return nullptr;
8710 
8711   ExprResult Diff;
8712   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8713   // 1]).
8714   if (NeedToReorganize) {
8715     Diff = Lower;
8716 
8717     if (RoundToStep) {
8718       // Lower - Step
8719       Diff =
8720           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8721       if (!Diff.isUsable())
8722         return nullptr;
8723     }
8724 
8725     // Lower - Step [+ 1]
8726     if (TestIsStrictOp)
8727       Diff = SemaRef.BuildBinOp(
8728           S, DefaultLoc, BO_Add, Diff.get(),
8729           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8730     if (!Diff.isUsable())
8731       return nullptr;
8732 
8733     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8734     if (!Diff.isUsable())
8735       return nullptr;
8736 
8737     // Upper - (Lower - Step [+ 1]).
8738     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8739     if (!Diff.isUsable())
8740       return nullptr;
8741   } else {
8742     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8743 
8744     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8745       // BuildBinOp already emitted error, this one is to point user to upper
8746       // and lower bound, and to tell what is passed to 'operator-'.
8747       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8748           << Upper->getSourceRange() << Lower->getSourceRange();
8749       return nullptr;
8750     }
8751 
8752     if (!Diff.isUsable())
8753       return nullptr;
8754 
8755     // Upper - Lower [- 1]
8756     if (TestIsStrictOp)
8757       Diff = SemaRef.BuildBinOp(
8758           S, DefaultLoc, BO_Sub, Diff.get(),
8759           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8760     if (!Diff.isUsable())
8761       return nullptr;
8762 
8763     if (RoundToStep) {
8764       // Upper - Lower [- 1] + Step
8765       Diff =
8766           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8767       if (!Diff.isUsable())
8768         return nullptr;
8769     }
8770   }
8771 
8772   // Parentheses (for dumping/debugging purposes only).
8773   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8774   if (!Diff.isUsable())
8775     return nullptr;
8776 
8777   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8778   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8779   if (!Diff.isUsable())
8780     return nullptr;
8781 
8782   return Diff.get();
8783 }
8784 
8785 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8786 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8787     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8788     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8789   QualType VarType = LCDecl->getType().getNonReferenceType();
8790   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8791       !SemaRef.getLangOpts().CPlusPlus)
8792     return nullptr;
8793   Expr *LBVal = LB;
8794   Expr *UBVal = UB;
8795   // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8796   // max(LB(MinVal), LB(MaxVal)))
8797   if (InitDependOnLC) {
8798     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8799     if (!IS.MinValue || !IS.MaxValue)
8800       return nullptr;
8801     // OuterVar = Min
8802     ExprResult MinValue =
8803         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8804     if (!MinValue.isUsable())
8805       return nullptr;
8806 
8807     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8808                                              IS.CounterVar, MinValue.get());
8809     if (!LBMinVal.isUsable())
8810       return nullptr;
8811     // OuterVar = Min, LBVal
8812     LBMinVal =
8813         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8814     if (!LBMinVal.isUsable())
8815       return nullptr;
8816     // (OuterVar = Min, LBVal)
8817     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8818     if (!LBMinVal.isUsable())
8819       return nullptr;
8820 
8821     // OuterVar = Max
8822     ExprResult MaxValue =
8823         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8824     if (!MaxValue.isUsable())
8825       return nullptr;
8826 
8827     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8828                                              IS.CounterVar, MaxValue.get());
8829     if (!LBMaxVal.isUsable())
8830       return nullptr;
8831     // OuterVar = Max, LBVal
8832     LBMaxVal =
8833         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8834     if (!LBMaxVal.isUsable())
8835       return nullptr;
8836     // (OuterVar = Max, LBVal)
8837     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8838     if (!LBMaxVal.isUsable())
8839       return nullptr;
8840 
8841     Expr *LBMin =
8842         tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8843     Expr *LBMax =
8844         tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8845     if (!LBMin || !LBMax)
8846       return nullptr;
8847     // LB(MinVal) < LB(MaxVal)
8848     ExprResult MinLessMaxRes =
8849         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8850     if (!MinLessMaxRes.isUsable())
8851       return nullptr;
8852     Expr *MinLessMax =
8853         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8854             .get();
8855     if (!MinLessMax)
8856       return nullptr;
8857     if (*TestIsLessOp) {
8858       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8859       // LB(MaxVal))
8860       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8861                                                     MinLessMax, LBMin, LBMax);
8862       if (!MinLB.isUsable())
8863         return nullptr;
8864       LBVal = MinLB.get();
8865     } else {
8866       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8867       // LB(MaxVal))
8868       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8869                                                     MinLessMax, LBMax, LBMin);
8870       if (!MaxLB.isUsable())
8871         return nullptr;
8872       LBVal = MaxLB.get();
8873     }
8874     // OuterVar = LB
8875     LBMinVal =
8876         SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8877     if (!LBMinVal.isUsable())
8878       return nullptr;
8879     LBVal = LBMinVal.get();
8880   }
8881   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8882   // min(UB(MinVal), UB(MaxVal))
8883   if (CondDependOnLC) {
8884     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8885     if (!IS.MinValue || !IS.MaxValue)
8886       return nullptr;
8887     // OuterVar = Min
8888     ExprResult MinValue =
8889         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8890     if (!MinValue.isUsable())
8891       return nullptr;
8892 
8893     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8894                                              IS.CounterVar, MinValue.get());
8895     if (!UBMinVal.isUsable())
8896       return nullptr;
8897     // OuterVar = Min, UBVal
8898     UBMinVal =
8899         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8900     if (!UBMinVal.isUsable())
8901       return nullptr;
8902     // (OuterVar = Min, UBVal)
8903     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8904     if (!UBMinVal.isUsable())
8905       return nullptr;
8906 
8907     // OuterVar = Max
8908     ExprResult MaxValue =
8909         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8910     if (!MaxValue.isUsable())
8911       return nullptr;
8912 
8913     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8914                                              IS.CounterVar, MaxValue.get());
8915     if (!UBMaxVal.isUsable())
8916       return nullptr;
8917     // OuterVar = Max, UBVal
8918     UBMaxVal =
8919         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8920     if (!UBMaxVal.isUsable())
8921       return nullptr;
8922     // (OuterVar = Max, UBVal)
8923     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8924     if (!UBMaxVal.isUsable())
8925       return nullptr;
8926 
8927     Expr *UBMin =
8928         tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8929     Expr *UBMax =
8930         tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8931     if (!UBMin || !UBMax)
8932       return nullptr;
8933     // UB(MinVal) > UB(MaxVal)
8934     ExprResult MinGreaterMaxRes =
8935         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8936     if (!MinGreaterMaxRes.isUsable())
8937       return nullptr;
8938     Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8939                                           Captures, ".min_greater_max")
8940                               .get();
8941     if (!MinGreaterMax)
8942       return nullptr;
8943     if (*TestIsLessOp) {
8944       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8945       // UB(MaxVal))
8946       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8947           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8948       if (!MaxUB.isUsable())
8949         return nullptr;
8950       UBVal = MaxUB.get();
8951     } else {
8952       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8953       // UB(MaxVal))
8954       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8955           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8956       if (!MinUB.isUsable())
8957         return nullptr;
8958       UBVal = MinUB.get();
8959     }
8960   }
8961   Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8962   Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8963   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8964   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8965   if (!Upper || !Lower)
8966     return nullptr;
8967 
8968   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8969                                       Step, VarType, TestIsStrictOp,
8970                                       /*RoundToStep=*/true, Captures);
8971   if (!Diff.isUsable())
8972     return nullptr;
8973 
8974   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8975   QualType Type = Diff.get()->getType();
8976   ASTContext &C = SemaRef.Context;
8977   bool UseVarType = VarType->hasIntegerRepresentation() &&
8978                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8979   if (!Type->isIntegerType() || UseVarType) {
8980     unsigned NewSize =
8981         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8982     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8983                                : Type->hasSignedIntegerRepresentation();
8984     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8985     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8986       Diff = SemaRef.PerformImplicitConversion(
8987           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8988       if (!Diff.isUsable())
8989         return nullptr;
8990     }
8991   }
8992   if (LimitedType) {
8993     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8994     if (NewSize != C.getTypeSize(Type)) {
8995       if (NewSize < C.getTypeSize(Type)) {
8996         assert(NewSize == 64 && "incorrect loop var size");
8997         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8998             << InitSrcRange << ConditionSrcRange;
8999       }
9000       QualType NewType = C.getIntTypeForBitwidth(
9001           NewSize, Type->hasSignedIntegerRepresentation() ||
9002                        C.getTypeSize(Type) < NewSize);
9003       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
9004         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
9005                                                  Sema::AA_Converting, true);
9006         if (!Diff.isUsable())
9007           return nullptr;
9008       }
9009     }
9010   }
9011 
9012   return Diff.get();
9013 }
9014 
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const9015 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
9016     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
9017   // Do not build for iterators, they cannot be used in non-rectangular loop
9018   // nests.
9019   if (LCDecl->getType()->isRecordType())
9020     return std::make_pair(nullptr, nullptr);
9021   // If we subtract, the min is in the condition, otherwise the min is in the
9022   // init value.
9023   Expr *MinExpr = nullptr;
9024   Expr *MaxExpr = nullptr;
9025   Expr *LBExpr = *TestIsLessOp ? LB : UB;
9026   Expr *UBExpr = *TestIsLessOp ? UB : LB;
9027   bool LBNonRect =
9028       *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
9029   bool UBNonRect =
9030       *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
9031   Expr *Lower =
9032       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
9033   Expr *Upper =
9034       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
9035   if (!Upper || !Lower)
9036     return std::make_pair(nullptr, nullptr);
9037 
9038   if (*TestIsLessOp)
9039     MinExpr = Lower;
9040   else
9041     MaxExpr = Upper;
9042 
9043   // Build minimum/maximum value based on number of iterations.
9044   QualType VarType = LCDecl->getType().getNonReferenceType();
9045 
9046   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9047                                       Step, VarType, TestIsStrictOp,
9048                                       /*RoundToStep=*/false, Captures);
9049   if (!Diff.isUsable())
9050     return std::make_pair(nullptr, nullptr);
9051 
9052   // ((Upper - Lower [- 1]) / Step) * Step
9053   // Parentheses (for dumping/debugging purposes only).
9054   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9055   if (!Diff.isUsable())
9056     return std::make_pair(nullptr, nullptr);
9057 
9058   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
9059   if (!NewStep.isUsable())
9060     return std::make_pair(nullptr, nullptr);
9061   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
9062   if (!Diff.isUsable())
9063     return std::make_pair(nullptr, nullptr);
9064 
9065   // Parentheses (for dumping/debugging purposes only).
9066   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9067   if (!Diff.isUsable())
9068     return std::make_pair(nullptr, nullptr);
9069 
9070   // Convert to the ptrdiff_t, if original type is pointer.
9071   if (VarType->isAnyPointerType() &&
9072       !SemaRef.Context.hasSameType(
9073           Diff.get()->getType(),
9074           SemaRef.Context.getUnsignedPointerDiffType())) {
9075     Diff = SemaRef.PerformImplicitConversion(
9076         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
9077         Sema::AA_Converting, /*AllowExplicit=*/true);
9078   }
9079   if (!Diff.isUsable())
9080     return std::make_pair(nullptr, nullptr);
9081 
9082   if (*TestIsLessOp) {
9083     // MinExpr = Lower;
9084     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
9085     Diff = SemaRef.BuildBinOp(
9086         S, DefaultLoc, BO_Add,
9087         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
9088         Diff.get());
9089     if (!Diff.isUsable())
9090       return std::make_pair(nullptr, nullptr);
9091   } else {
9092     // MaxExpr = Upper;
9093     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
9094     Diff = SemaRef.BuildBinOp(
9095         S, DefaultLoc, BO_Sub,
9096         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
9097         Diff.get());
9098     if (!Diff.isUsable())
9099       return std::make_pair(nullptr, nullptr);
9100   }
9101 
9102   // Convert to the original type.
9103   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
9104     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
9105                                              Sema::AA_Converting,
9106                                              /*AllowExplicit=*/true);
9107   if (!Diff.isUsable())
9108     return std::make_pair(nullptr, nullptr);
9109 
9110   Sema::TentativeAnalysisScope Trap(SemaRef);
9111   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
9112   if (!Diff.isUsable())
9113     return std::make_pair(nullptr, nullptr);
9114 
9115   if (*TestIsLessOp)
9116     MaxExpr = Diff.get();
9117   else
9118     MinExpr = Diff.get();
9119 
9120   return std::make_pair(MinExpr, MaxExpr);
9121 }
9122 
buildFinalCondition(Scope * S) const9123 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
9124   if (InitDependOnLC || CondDependOnLC)
9125     return Condition;
9126   return nullptr;
9127 }
9128 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const9129 Expr *OpenMPIterationSpaceChecker::buildPreCond(
9130     Scope *S, Expr *Cond,
9131     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
9132   // Do not build a precondition when the condition/initialization is dependent
9133   // to prevent pessimistic early loop exit.
9134   // TODO: this can be improved by calculating min/max values but not sure that
9135   // it will be very effective.
9136   if (CondDependOnLC || InitDependOnLC)
9137     return SemaRef
9138         .PerformImplicitConversion(
9139             SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
9140             SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9141             /*AllowExplicit=*/true)
9142         .get();
9143 
9144   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
9145   Sema::TentativeAnalysisScope Trap(SemaRef);
9146 
9147   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9148   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9149   if (!NewLB.isUsable() || !NewUB.isUsable())
9150     return nullptr;
9151 
9152   ExprResult CondExpr =
9153       SemaRef.BuildBinOp(S, DefaultLoc,
9154                          *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9155                                        : (TestIsStrictOp ? BO_GT : BO_GE),
9156                          NewLB.get(), NewUB.get());
9157   if (CondExpr.isUsable()) {
9158     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
9159                                                 SemaRef.Context.BoolTy))
9160       CondExpr = SemaRef.PerformImplicitConversion(
9161           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9162           /*AllowExplicit=*/true);
9163   }
9164 
9165   // Otherwise use original loop condition and evaluate it in runtime.
9166   return CondExpr.isUsable() ? CondExpr.get() : Cond;
9167 }
9168 
9169 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const9170 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9171     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9172     DSAStackTy &DSA) const {
9173   auto *VD = dyn_cast<VarDecl>(LCDecl);
9174   if (!VD) {
9175     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
9176     DeclRefExpr *Ref = buildDeclRefExpr(
9177         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
9178     const DSAStackTy::DSAVarData Data =
9179         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
9180     // If the loop control decl is explicitly marked as private, do not mark it
9181     // as captured again.
9182     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
9183       Captures.insert(std::make_pair(LCRef, Ref));
9184     return Ref;
9185   }
9186   return cast<DeclRefExpr>(LCRef);
9187 }
9188 
buildPrivateCounterVar() const9189 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9190   if (LCDecl && !LCDecl->isInvalidDecl()) {
9191     QualType Type = LCDecl->getType().getNonReferenceType();
9192     VarDecl *PrivateVar = buildVarDecl(
9193         SemaRef, DefaultLoc, Type, LCDecl->getName(),
9194         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9195         isa<VarDecl>(LCDecl)
9196             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9197             : nullptr);
9198     if (PrivateVar->isInvalidDecl())
9199       return nullptr;
9200     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9201   }
9202   return nullptr;
9203 }
9204 
9205 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const9206 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9207 
9208 /// Build step of the counter be used for codegen.
buildCounterStep() const9209 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9210 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)9211 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9212     Scope *S, Expr *Counter,
9213     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9214     Expr *Inc, OverloadedOperatorKind OOK) {
9215   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9216   if (!Cnt)
9217     return nullptr;
9218   if (Inc) {
9219     assert((OOK == OO_Plus || OOK == OO_Minus) &&
9220            "Expected only + or - operations for depend clauses.");
9221     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9222     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9223     if (!Cnt)
9224       return nullptr;
9225   }
9226   QualType VarType = LCDecl->getType().getNonReferenceType();
9227   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9228       !SemaRef.getLangOpts().CPlusPlus)
9229     return nullptr;
9230   // Upper - Lower
9231   Expr *Upper =
9232       *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9233   Expr *Lower =
9234       *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9235   if (!Upper || !Lower)
9236     return nullptr;
9237 
9238   ExprResult Diff = calculateNumIters(
9239       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9240       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9241   if (!Diff.isUsable())
9242     return nullptr;
9243 
9244   return Diff.get();
9245 }
9246 } // namespace
9247 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)9248 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9249   assert(getLangOpts().OpenMP && "OpenMP is not active.");
9250   assert(Init && "Expected loop in canonical form.");
9251   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9252   if (AssociatedLoops > 0 &&
9253       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
9254     DSAStack->loopStart();
9255     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9256                                     *DSAStack, ForLoc);
9257     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9258       if (ValueDecl *D = ISC.getLoopDecl()) {
9259         auto *VD = dyn_cast<VarDecl>(D);
9260         DeclRefExpr *PrivateRef = nullptr;
9261         if (!VD) {
9262           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9263             VD = Private;
9264           } else {
9265             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9266                                       /*WithInit=*/false);
9267             VD = cast<VarDecl>(PrivateRef->getDecl());
9268           }
9269         }
9270         DSAStack->addLoopControlVariable(D, VD);
9271         const Decl *LD = DSAStack->getPossiblyLoopCunter();
9272         if (LD != D->getCanonicalDecl()) {
9273           DSAStack->resetPossibleLoopCounter();
9274           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9275             MarkDeclarationsReferencedInExpr(
9276                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9277                                  Var->getType().getNonLValueExprType(Context),
9278                                  ForLoc, /*RefersToCapture=*/true));
9279         }
9280         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9281         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9282         // Referenced in a Construct, C/C++]. The loop iteration variable in the
9283         // associated for-loop of a simd construct with just one associated
9284         // for-loop may be listed in a linear clause with a constant-linear-step
9285         // that is the increment of the associated for-loop. The loop iteration
9286         // variable(s) in the associated for-loop(s) of a for or parallel for
9287         // construct may be listed in a private or lastprivate clause.
9288         DSAStackTy::DSAVarData DVar =
9289             DSAStack->getTopDSA(D, /*FromParent=*/false);
9290         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9291         // is declared in the loop and it is predetermined as a private.
9292         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9293         OpenMPClauseKind PredeterminedCKind =
9294             isOpenMPSimdDirective(DKind)
9295                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9296                 : OMPC_private;
9297         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9298               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9299               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9300                                          DVar.CKind != OMPC_private))) ||
9301              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9302                DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9303                DKind == OMPD_parallel_master_taskloop ||
9304                DKind == OMPD_parallel_masked_taskloop ||
9305                isOpenMPDistributeDirective(DKind)) &&
9306               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9307               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9308             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9309           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9310               << getOpenMPClauseName(DVar.CKind)
9311               << getOpenMPDirectiveName(DKind)
9312               << getOpenMPClauseName(PredeterminedCKind);
9313           if (DVar.RefExpr == nullptr)
9314             DVar.CKind = PredeterminedCKind;
9315           reportOriginalDsa(*this, DSAStack, D, DVar,
9316                             /*IsLoopIterVar=*/true);
9317         } else if (LoopDeclRefExpr) {
9318           // Make the loop iteration variable private (for worksharing
9319           // constructs), linear (for simd directives with the only one
9320           // associated loop) or lastprivate (for simd directives with several
9321           // collapsed or ordered loops).
9322           if (DVar.CKind == OMPC_unknown)
9323             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9324                              PrivateRef);
9325         }
9326       }
9327     }
9328     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9329   }
9330 }
9331 
9332 namespace {
9333 // Utility for openmp doacross clause kind
9334 class OMPDoacrossKind {
9335 public:
isSource(const OMPDoacrossClause * C)9336   bool isSource(const OMPDoacrossClause *C) {
9337     return C->getDependenceType() == OMPC_DOACROSS_source ||
9338            C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9339   }
isSink(const OMPDoacrossClause * C)9340   bool isSink(const OMPDoacrossClause *C) {
9341     return C->getDependenceType() == OMPC_DOACROSS_sink;
9342   }
isSinkIter(const OMPDoacrossClause * C)9343   bool isSinkIter(const OMPDoacrossClause *C) {
9344     return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9345   }
9346 };
9347 } // namespace
9348 /// Called on a for stmt to check and extract its iteration space
9349 /// 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)9350 static bool checkOpenMPIterationSpace(
9351     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9352     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9353     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9354     Expr *OrderedLoopCountExpr,
9355     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9356     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9357     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9358   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9359   // OpenMP [2.9.1, Canonical Loop Form]
9360   //   for (init-expr; test-expr; incr-expr) structured-block
9361   //   for (range-decl: range-expr) structured-block
9362   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9363     S = CanonLoop->getLoopStmt();
9364   auto *For = dyn_cast_or_null<ForStmt>(S);
9365   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9366   // Ranged for is supported only in OpenMP 5.0.
9367   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9368     OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 ||
9369                               DSA.getMappedDirective() == OMPD_unknown)
9370                                  ? DKind
9371                                  : DSA.getMappedDirective();
9372     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9373         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9374         << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9375         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9376     if (TotalNestedLoopCount > 1) {
9377       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9378         SemaRef.Diag(DSA.getConstructLoc(),
9379                      diag::note_omp_collapse_ordered_expr)
9380             << 2 << CollapseLoopCountExpr->getSourceRange()
9381             << OrderedLoopCountExpr->getSourceRange();
9382       else if (CollapseLoopCountExpr)
9383         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9384                      diag::note_omp_collapse_ordered_expr)
9385             << 0 << CollapseLoopCountExpr->getSourceRange();
9386       else
9387         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9388                      diag::note_omp_collapse_ordered_expr)
9389             << 1 << OrderedLoopCountExpr->getSourceRange();
9390     }
9391     return true;
9392   }
9393   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9394          "No loop body.");
9395   // Postpone analysis in dependent contexts for ranged for loops.
9396   if (CXXFor && SemaRef.CurContext->isDependentContext())
9397     return false;
9398 
9399   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9400                                   For ? For->getForLoc() : CXXFor->getForLoc());
9401 
9402   // Check init.
9403   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9404   if (ISC.checkAndSetInit(Init))
9405     return true;
9406 
9407   bool HasErrors = false;
9408 
9409   // Check loop variable's type.
9410   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9411     // OpenMP [2.6, Canonical Loop Form]
9412     // Var is one of the following:
9413     //   A variable of signed or unsigned integer type.
9414     //   For C++, a variable of a random access iterator type.
9415     //   For C, a variable of a pointer type.
9416     QualType VarType = LCDecl->getType().getNonReferenceType();
9417     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9418         !VarType->isPointerType() &&
9419         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9420       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9421           << SemaRef.getLangOpts().CPlusPlus;
9422       HasErrors = true;
9423     }
9424 
9425     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9426     // a Construct
9427     // The loop iteration variable(s) in the associated for-loop(s) of a for or
9428     // parallel for construct is (are) private.
9429     // The loop iteration variable in the associated for-loop of a simd
9430     // construct with just one associated for-loop is linear with a
9431     // constant-linear-step that is the increment of the associated for-loop.
9432     // Exclude loop var from the list of variables with implicitly defined data
9433     // sharing attributes.
9434     VarsWithImplicitDSA.erase(LCDecl);
9435 
9436     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9437 
9438     // Check test-expr.
9439     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9440 
9441     // Check incr-expr.
9442     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9443   }
9444 
9445   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9446     return HasErrors;
9447 
9448   // Build the loop's iteration space representation.
9449   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9450       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9451   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9452       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9453                              (isOpenMPWorksharingDirective(DKind) ||
9454                               isOpenMPGenericLoopDirective(DKind) ||
9455                               isOpenMPTaskLoopDirective(DKind) ||
9456                               isOpenMPDistributeDirective(DKind) ||
9457                               isOpenMPLoopTransformationDirective(DKind)),
9458                              Captures);
9459   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9460       ISC.buildCounterVar(Captures, DSA);
9461   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9462       ISC.buildPrivateCounterVar();
9463   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9464   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9465   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9466   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9467       ISC.getConditionSrcRange();
9468   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9469       ISC.getIncrementSrcRange();
9470   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9471   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9472       ISC.isStrictTestOp();
9473   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9474            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9475       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9476   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9477       ISC.buildFinalCondition(DSA.getCurScope());
9478   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9479       ISC.doesInitDependOnLC();
9480   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9481       ISC.doesCondDependOnLC();
9482   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9483       ISC.getLoopDependentIdx();
9484 
9485   HasErrors |=
9486       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9487        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9488        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9489        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9490        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9491        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9492   if (!HasErrors && DSA.isOrderedRegion()) {
9493     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9494       if (CurrentNestedLoopCount <
9495           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9496         DSA.getOrderedRegionParam().second->setLoopNumIterations(
9497             CurrentNestedLoopCount,
9498             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9499         DSA.getOrderedRegionParam().second->setLoopCounter(
9500             CurrentNestedLoopCount,
9501             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9502       }
9503     }
9504     for (auto &Pair : DSA.getDoacrossDependClauses()) {
9505       auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9506       auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9507       unsigned NumLoops =
9508           DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9509       if (CurrentNestedLoopCount >= NumLoops) {
9510         // Erroneous case - clause has some problems.
9511         continue;
9512       }
9513       if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9514           Pair.second.size() <= CurrentNestedLoopCount) {
9515         // Erroneous case - clause has some problems.
9516         DependC->setLoopData(CurrentNestedLoopCount, nullptr);
9517         continue;
9518       }
9519       OMPDoacrossKind ODK;
9520       if (DoacrossC && ODK.isSink(DoacrossC) &&
9521           Pair.second.size() <= CurrentNestedLoopCount) {
9522         // Erroneous case - clause has some problems.
9523         DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
9524         continue;
9525       }
9526       Expr *CntValue;
9527       SourceLocation DepLoc =
9528           DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9529       if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9530           (DoacrossC && ODK.isSource(DoacrossC)))
9531         CntValue = ISC.buildOrderedLoopData(
9532             DSA.getCurScope(),
9533             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9534             DepLoc);
9535       else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9536         Expr *Cnt = SemaRef
9537                         .DefaultLvalueConversion(
9538                             ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9539                         .get();
9540         if (!Cnt)
9541           continue;
9542         // build CounterVar - 1
9543         Expr *Inc =
9544             SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
9545                 .get();
9546         CntValue = ISC.buildOrderedLoopData(
9547             DSA.getCurScope(),
9548             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9549             DepLoc, Inc, clang::OO_Minus);
9550       } else
9551         CntValue = ISC.buildOrderedLoopData(
9552             DSA.getCurScope(),
9553             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9554             DepLoc, Pair.second[CurrentNestedLoopCount].first,
9555             Pair.second[CurrentNestedLoopCount].second);
9556       if (DependC)
9557         DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9558       else
9559         DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9560     }
9561   }
9562 
9563   return HasErrors;
9564 }
9565 
9566 /// Build 'VarRef = Start.
9567 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)9568 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9569                  ExprResult Start, bool IsNonRectangularLB,
9570                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9571   // Build 'VarRef = Start.
9572   ExprResult NewStart = IsNonRectangularLB
9573                             ? Start.get()
9574                             : tryBuildCapture(SemaRef, Start.get(), Captures);
9575   if (!NewStart.isUsable())
9576     return ExprError();
9577   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9578                                    VarRef.get()->getType())) {
9579     NewStart = SemaRef.PerformImplicitConversion(
9580         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9581         /*AllowExplicit=*/true);
9582     if (!NewStart.isUsable())
9583       return ExprError();
9584   }
9585 
9586   ExprResult Init =
9587       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9588   return Init;
9589 }
9590 
9591 /// 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)9592 static ExprResult buildCounterUpdate(
9593     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9594     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9595     bool IsNonRectangularLB,
9596     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9597   // Add parentheses (for debugging purposes only).
9598   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9599   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9600       !Step.isUsable())
9601     return ExprError();
9602 
9603   ExprResult NewStep = Step;
9604   if (Captures)
9605     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9606   if (NewStep.isInvalid())
9607     return ExprError();
9608   ExprResult Update =
9609       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9610   if (!Update.isUsable())
9611     return ExprError();
9612 
9613   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9614   // 'VarRef = Start (+|-) Iter * Step'.
9615   if (!Start.isUsable())
9616     return ExprError();
9617   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9618   if (!NewStart.isUsable())
9619     return ExprError();
9620   if (Captures && !IsNonRectangularLB)
9621     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9622   if (NewStart.isInvalid())
9623     return ExprError();
9624 
9625   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9626   ExprResult SavedUpdate = Update;
9627   ExprResult UpdateVal;
9628   if (VarRef.get()->getType()->isOverloadableType() ||
9629       NewStart.get()->getType()->isOverloadableType() ||
9630       Update.get()->getType()->isOverloadableType()) {
9631     Sema::TentativeAnalysisScope Trap(SemaRef);
9632 
9633     Update =
9634         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9635     if (Update.isUsable()) {
9636       UpdateVal =
9637           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9638                              VarRef.get(), SavedUpdate.get());
9639       if (UpdateVal.isUsable()) {
9640         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9641                                             UpdateVal.get());
9642       }
9643     }
9644   }
9645 
9646   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9647   if (!Update.isUsable() || !UpdateVal.isUsable()) {
9648     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9649                                 NewStart.get(), SavedUpdate.get());
9650     if (!Update.isUsable())
9651       return ExprError();
9652 
9653     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9654                                      VarRef.get()->getType())) {
9655       Update = SemaRef.PerformImplicitConversion(
9656           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9657       if (!Update.isUsable())
9658         return ExprError();
9659     }
9660 
9661     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9662   }
9663   return Update;
9664 }
9665 
9666 /// Convert integer expression \a E to make it have at least \a Bits
9667 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)9668 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9669   if (E == nullptr)
9670     return ExprError();
9671   ASTContext &C = SemaRef.Context;
9672   QualType OldType = E->getType();
9673   unsigned HasBits = C.getTypeSize(OldType);
9674   if (HasBits >= Bits)
9675     return ExprResult(E);
9676   // OK to convert to signed, because new type has more bits than old.
9677   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9678   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9679                                            true);
9680 }
9681 
9682 /// Check if the given expression \a E is a constant integer that fits
9683 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)9684 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9685   if (E == nullptr)
9686     return false;
9687   if (std::optional<llvm::APSInt> Result =
9688           E->getIntegerConstantExpr(SemaRef.Context))
9689     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9690   return false;
9691 }
9692 
9693 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)9694 static Stmt *buildPreInits(ASTContext &Context,
9695                            MutableArrayRef<Decl *> PreInits) {
9696   if (!PreInits.empty()) {
9697     return new (Context) DeclStmt(
9698         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9699         SourceLocation(), SourceLocation());
9700   }
9701   return nullptr;
9702 }
9703 
9704 /// Build preinits statement for the given declarations.
9705 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)9706 buildPreInits(ASTContext &Context,
9707               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9708   if (!Captures.empty()) {
9709     SmallVector<Decl *, 16> PreInits;
9710     for (const auto &Pair : Captures)
9711       PreInits.push_back(Pair.second->getDecl());
9712     return buildPreInits(Context, PreInits);
9713   }
9714   return nullptr;
9715 }
9716 
9717 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)9718 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9719   Expr *PostUpdate = nullptr;
9720   if (!PostUpdates.empty()) {
9721     for (Expr *E : PostUpdates) {
9722       Expr *ConvE = S.BuildCStyleCastExpr(
9723                          E->getExprLoc(),
9724                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9725                          E->getExprLoc(), E)
9726                         .get();
9727       PostUpdate = PostUpdate
9728                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9729                                               PostUpdate, ConvE)
9730                              .get()
9731                        : ConvE;
9732     }
9733   }
9734   return PostUpdate;
9735 }
9736 
9737 /// Called on a for stmt to check itself and nested loops (if any).
9738 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9739 /// number of collapsed loops otherwise.
9740 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopBasedDirective::HelperExprs & Built)9741 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9742                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9743                 DSAStackTy &DSA,
9744                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9745                 OMPLoopBasedDirective::HelperExprs &Built) {
9746   unsigned NestedLoopCount = 1;
9747   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9748                                     !isOpenMPLoopTransformationDirective(DKind);
9749 
9750   if (CollapseLoopCountExpr) {
9751     // Found 'collapse' clause - calculate collapse number.
9752     Expr::EvalResult Result;
9753     if (!CollapseLoopCountExpr->isValueDependent() &&
9754         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9755       NestedLoopCount = Result.Val.getInt().getLimitedValue();
9756     } else {
9757       Built.clear(/*Size=*/1);
9758       return 1;
9759     }
9760   }
9761   unsigned OrderedLoopCount = 1;
9762   if (OrderedLoopCountExpr) {
9763     // Found 'ordered' clause - calculate collapse number.
9764     Expr::EvalResult EVResult;
9765     if (!OrderedLoopCountExpr->isValueDependent() &&
9766         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9767                                             SemaRef.getASTContext())) {
9768       llvm::APSInt Result = EVResult.Val.getInt();
9769       if (Result.getLimitedValue() < NestedLoopCount) {
9770         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9771                      diag::err_omp_wrong_ordered_loop_count)
9772             << OrderedLoopCountExpr->getSourceRange();
9773         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9774                      diag::note_collapse_loop_count)
9775             << CollapseLoopCountExpr->getSourceRange();
9776       }
9777       OrderedLoopCount = Result.getLimitedValue();
9778     } else {
9779       Built.clear(/*Size=*/1);
9780       return 1;
9781     }
9782   }
9783   // This is helper routine for loop directives (e.g., 'for', 'simd',
9784   // 'for simd', etc.).
9785   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9786   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9787   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9788   if (!OMPLoopBasedDirective::doForAllLoops(
9789           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9790           SupportsNonPerfectlyNested, NumLoops,
9791           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9792            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9793            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9794             if (checkOpenMPIterationSpace(
9795                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9796                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9797                     VarsWithImplicitDSA, IterSpaces, Captures))
9798               return true;
9799             if (Cnt > 0 && Cnt >= NestedLoopCount &&
9800                 IterSpaces[Cnt].CounterVar) {
9801               // Handle initialization of captured loop iterator variables.
9802               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9803               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9804                 Captures[DRE] = DRE;
9805               }
9806             }
9807             return false;
9808           },
9809           [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9810             Stmt *DependentPreInits = Transform->getPreInits();
9811             if (!DependentPreInits)
9812               return;
9813             for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9814               auto *D = cast<VarDecl>(C);
9815               DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9816                                                   Transform->getBeginLoc());
9817               Captures[Ref] = Ref;
9818             }
9819           }))
9820     return 0;
9821 
9822   Built.clear(/* size */ NestedLoopCount);
9823 
9824   if (SemaRef.CurContext->isDependentContext())
9825     return NestedLoopCount;
9826 
9827   // An example of what is generated for the following code:
9828   //
9829   //   #pragma omp simd collapse(2) ordered(2)
9830   //   for (i = 0; i < NI; ++i)
9831   //     for (k = 0; k < NK; ++k)
9832   //       for (j = J0; j < NJ; j+=2) {
9833   //         <loop body>
9834   //       }
9835   //
9836   // We generate the code below.
9837   // Note: the loop body may be outlined in CodeGen.
9838   // Note: some counters may be C++ classes, operator- is used to find number of
9839   // iterations and operator+= to calculate counter value.
9840   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9841   // or i64 is currently supported).
9842   //
9843   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9844   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9845   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9846   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9847   //     // similar updates for vars in clauses (e.g. 'linear')
9848   //     <loop body (using local i and j)>
9849   //   }
9850   //   i = NI; // assign final values of counters
9851   //   j = NJ;
9852   //
9853 
9854   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9855   // the iteration counts of the collapsed for loops.
9856   // Precondition tests if there is at least one iteration (all conditions are
9857   // true).
9858   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9859   Expr *N0 = IterSpaces[0].NumIterations;
9860   ExprResult LastIteration32 =
9861       widenIterationCount(/*Bits=*/32,
9862                           SemaRef
9863                               .PerformImplicitConversion(
9864                                   N0->IgnoreImpCasts(), N0->getType(),
9865                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9866                               .get(),
9867                           SemaRef);
9868   ExprResult LastIteration64 = widenIterationCount(
9869       /*Bits=*/64,
9870       SemaRef
9871           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9872                                      Sema::AA_Converting,
9873                                      /*AllowExplicit=*/true)
9874           .get(),
9875       SemaRef);
9876 
9877   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9878     return NestedLoopCount;
9879 
9880   ASTContext &C = SemaRef.Context;
9881   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9882 
9883   Scope *CurScope = DSA.getCurScope();
9884   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9885     if (PreCond.isUsable()) {
9886       PreCond =
9887           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9888                              PreCond.get(), IterSpaces[Cnt].PreCond);
9889     }
9890     Expr *N = IterSpaces[Cnt].NumIterations;
9891     SourceLocation Loc = N->getExprLoc();
9892     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9893     if (LastIteration32.isUsable())
9894       LastIteration32 = SemaRef.BuildBinOp(
9895           CurScope, Loc, BO_Mul, LastIteration32.get(),
9896           SemaRef
9897               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9898                                          Sema::AA_Converting,
9899                                          /*AllowExplicit=*/true)
9900               .get());
9901     if (LastIteration64.isUsable())
9902       LastIteration64 = SemaRef.BuildBinOp(
9903           CurScope, Loc, BO_Mul, LastIteration64.get(),
9904           SemaRef
9905               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9906                                          Sema::AA_Converting,
9907                                          /*AllowExplicit=*/true)
9908               .get());
9909   }
9910 
9911   // Choose either the 32-bit or 64-bit version.
9912   ExprResult LastIteration = LastIteration64;
9913   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9914       (LastIteration32.isUsable() &&
9915        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9916        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9917         fitsInto(
9918             /*Bits=*/32,
9919             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9920             LastIteration64.get(), SemaRef))))
9921     LastIteration = LastIteration32;
9922   QualType VType = LastIteration.get()->getType();
9923   QualType RealVType = VType;
9924   QualType StrideVType = VType;
9925   if (isOpenMPTaskLoopDirective(DKind)) {
9926     VType =
9927         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9928     StrideVType =
9929         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9930   }
9931 
9932   if (!LastIteration.isUsable())
9933     return 0;
9934 
9935   // Save the number of iterations.
9936   ExprResult NumIterations = LastIteration;
9937   {
9938     LastIteration = SemaRef.BuildBinOp(
9939         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9940         LastIteration.get(),
9941         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9942     if (!LastIteration.isUsable())
9943       return 0;
9944   }
9945 
9946   // Calculate the last iteration number beforehand instead of doing this on
9947   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9948   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9949   ExprResult CalcLastIteration;
9950   if (!IsConstant) {
9951     ExprResult SaveRef =
9952         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9953     LastIteration = SaveRef;
9954 
9955     // Prepare SaveRef + 1.
9956     NumIterations = SemaRef.BuildBinOp(
9957         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9958         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9959     if (!NumIterations.isUsable())
9960       return 0;
9961   }
9962 
9963   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9964 
9965   // Build variables passed into runtime, necessary for worksharing directives.
9966   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9967   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9968       isOpenMPDistributeDirective(DKind) ||
9969       isOpenMPGenericLoopDirective(DKind) ||
9970       isOpenMPLoopTransformationDirective(DKind)) {
9971     // Lower bound variable, initialized with zero.
9972     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9973     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9974     SemaRef.AddInitializerToDecl(LBDecl,
9975                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9976                                  /*DirectInit*/ false);
9977 
9978     // Upper bound variable, initialized with last iteration number.
9979     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9980     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9981     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9982                                  /*DirectInit*/ false);
9983 
9984     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9985     // This will be used to implement clause 'lastprivate'.
9986     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9987     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9988     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9989     SemaRef.AddInitializerToDecl(ILDecl,
9990                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9991                                  /*DirectInit*/ false);
9992 
9993     // Stride variable returned by runtime (we initialize it to 1 by default).
9994     VarDecl *STDecl =
9995         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9996     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9997     SemaRef.AddInitializerToDecl(STDecl,
9998                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9999                                  /*DirectInit*/ false);
10000 
10001     // Build expression: UB = min(UB, LastIteration)
10002     // It is necessary for CodeGen of directives with static scheduling.
10003     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
10004                                                 UB.get(), LastIteration.get());
10005     ExprResult CondOp = SemaRef.ActOnConditionalOp(
10006         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
10007         LastIteration.get(), UB.get());
10008     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
10009                              CondOp.get());
10010     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
10011 
10012     // If we have a combined directive that combines 'distribute', 'for' or
10013     // 'simd' we need to be able to access the bounds of the schedule of the
10014     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
10015     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
10016     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10017       // Lower bound variable, initialized with zero.
10018       VarDecl *CombLBDecl =
10019           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
10020       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
10021       SemaRef.AddInitializerToDecl(
10022           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
10023           /*DirectInit*/ false);
10024 
10025       // Upper bound variable, initialized with last iteration number.
10026       VarDecl *CombUBDecl =
10027           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
10028       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
10029       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
10030                                    /*DirectInit*/ false);
10031 
10032       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
10033           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
10034       ExprResult CombCondOp =
10035           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
10036                                      LastIteration.get(), CombUB.get());
10037       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
10038                                    CombCondOp.get());
10039       CombEUB =
10040           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
10041 
10042       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10043       // We expect to have at least 2 more parameters than the 'parallel'
10044       // directive does - the lower and upper bounds of the previous schedule.
10045       assert(CD->getNumParams() >= 4 &&
10046              "Unexpected number of parameters in loop combined directive");
10047 
10048       // Set the proper type for the bounds given what we learned from the
10049       // enclosed loops.
10050       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
10051       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
10052 
10053       // Previous lower and upper bounds are obtained from the region
10054       // parameters.
10055       PrevLB =
10056           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
10057       PrevUB =
10058           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
10059     }
10060   }
10061 
10062   // Build the iteration variable and its initialization before loop.
10063   ExprResult IV;
10064   ExprResult Init, CombInit;
10065   {
10066     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
10067     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
10068     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
10069                  isOpenMPGenericLoopDirective(DKind) ||
10070                  isOpenMPTaskLoopDirective(DKind) ||
10071                  isOpenMPDistributeDirective(DKind) ||
10072                  isOpenMPLoopTransformationDirective(DKind))
10073                     ? LB.get()
10074                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
10075     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
10076     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
10077 
10078     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10079       Expr *CombRHS =
10080           (isOpenMPWorksharingDirective(DKind) ||
10081            isOpenMPGenericLoopDirective(DKind) ||
10082            isOpenMPTaskLoopDirective(DKind) ||
10083            isOpenMPDistributeDirective(DKind))
10084               ? CombLB.get()
10085               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
10086       CombInit =
10087           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
10088       CombInit =
10089           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
10090     }
10091   }
10092 
10093   bool UseStrictCompare =
10094       RealVType->hasUnsignedIntegerRepresentation() &&
10095       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
10096         return LIS.IsStrictCompare;
10097       });
10098   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
10099   // unsigned IV)) for worksharing loops.
10100   SourceLocation CondLoc = AStmt->getBeginLoc();
10101   Expr *BoundUB = UB.get();
10102   if (UseStrictCompare) {
10103     BoundUB =
10104         SemaRef
10105             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10106                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10107             .get();
10108     BoundUB =
10109         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
10110   }
10111   ExprResult Cond =
10112       (isOpenMPWorksharingDirective(DKind) ||
10113        isOpenMPGenericLoopDirective(DKind) ||
10114        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
10115        isOpenMPLoopTransformationDirective(DKind))
10116           ? SemaRef.BuildBinOp(CurScope, CondLoc,
10117                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
10118                                BoundUB)
10119           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10120                                NumIterations.get());
10121   ExprResult CombDistCond;
10122   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10123     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10124                                       NumIterations.get());
10125   }
10126 
10127   ExprResult CombCond;
10128   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10129     Expr *BoundCombUB = CombUB.get();
10130     if (UseStrictCompare) {
10131       BoundCombUB =
10132           SemaRef
10133               .BuildBinOp(
10134                   CurScope, CondLoc, BO_Add, BoundCombUB,
10135                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10136               .get();
10137       BoundCombUB =
10138           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
10139               .get();
10140     }
10141     CombCond =
10142         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10143                            IV.get(), BoundCombUB);
10144   }
10145   // Loop increment (IV = IV + 1)
10146   SourceLocation IncLoc = AStmt->getBeginLoc();
10147   ExprResult Inc =
10148       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
10149                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
10150   if (!Inc.isUsable())
10151     return 0;
10152   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
10153   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
10154   if (!Inc.isUsable())
10155     return 0;
10156 
10157   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
10158   // Used for directives with static scheduling.
10159   // In combined construct, add combined version that use CombLB and CombUB
10160   // base variables for the update
10161   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10162   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
10163       isOpenMPGenericLoopDirective(DKind) ||
10164       isOpenMPDistributeDirective(DKind) ||
10165       isOpenMPLoopTransformationDirective(DKind)) {
10166     // LB + ST
10167     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
10168     if (!NextLB.isUsable())
10169       return 0;
10170     // LB = LB + ST
10171     NextLB =
10172         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
10173     NextLB =
10174         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
10175     if (!NextLB.isUsable())
10176       return 0;
10177     // UB + ST
10178     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
10179     if (!NextUB.isUsable())
10180       return 0;
10181     // UB = UB + ST
10182     NextUB =
10183         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
10184     NextUB =
10185         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
10186     if (!NextUB.isUsable())
10187       return 0;
10188     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10189       CombNextLB =
10190           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
10191       if (!NextLB.isUsable())
10192         return 0;
10193       // LB = LB + ST
10194       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
10195                                       CombNextLB.get());
10196       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
10197                                                /*DiscardedValue*/ false);
10198       if (!CombNextLB.isUsable())
10199         return 0;
10200       // UB + ST
10201       CombNextUB =
10202           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10203       if (!CombNextUB.isUsable())
10204         return 0;
10205       // UB = UB + ST
10206       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10207                                       CombNextUB.get());
10208       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10209                                                /*DiscardedValue*/ false);
10210       if (!CombNextUB.isUsable())
10211         return 0;
10212     }
10213   }
10214 
10215   // Create increment expression for distribute loop when combined in a same
10216   // directive with for as IV = IV + ST; ensure upper bound expression based
10217   // on PrevUB instead of NumIterations - used to implement 'for' when found
10218   // in combination with 'distribute', like in 'distribute parallel for'
10219   SourceLocation DistIncLoc = AStmt->getBeginLoc();
10220   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10221   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10222     DistCond = SemaRef.BuildBinOp(
10223         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
10224     assert(DistCond.isUsable() && "distribute cond expr was not built");
10225 
10226     DistInc =
10227         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10228     assert(DistInc.isUsable() && "distribute inc expr was not built");
10229     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10230                                  DistInc.get());
10231     DistInc =
10232         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
10233     assert(DistInc.isUsable() && "distribute inc expr was not built");
10234 
10235     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10236     // construct
10237     ExprResult NewPrevUB = PrevUB;
10238     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10239     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10240                                      PrevUB.get()->getType())) {
10241       NewPrevUB = SemaRef.BuildCStyleCastExpr(
10242           DistEUBLoc,
10243           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10244           DistEUBLoc, NewPrevUB.get());
10245       if (!NewPrevUB.isUsable())
10246         return 0;
10247     }
10248     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10249                                                 UB.get(), NewPrevUB.get());
10250     ExprResult CondOp = SemaRef.ActOnConditionalOp(
10251         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10252     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10253                                  CondOp.get());
10254     PrevEUB =
10255         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10256 
10257     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10258     // parallel for is in combination with a distribute directive with
10259     // schedule(static, 1)
10260     Expr *BoundPrevUB = PrevUB.get();
10261     if (UseStrictCompare) {
10262       BoundPrevUB =
10263           SemaRef
10264               .BuildBinOp(
10265                   CurScope, CondLoc, BO_Add, BoundPrevUB,
10266                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10267               .get();
10268       BoundPrevUB =
10269           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10270               .get();
10271     }
10272     ParForInDistCond =
10273         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10274                            IV.get(), BoundPrevUB);
10275   }
10276 
10277   // Build updates and final values of the loop counters.
10278   bool HasErrors = false;
10279   Built.Counters.resize(NestedLoopCount);
10280   Built.Inits.resize(NestedLoopCount);
10281   Built.Updates.resize(NestedLoopCount);
10282   Built.Finals.resize(NestedLoopCount);
10283   Built.DependentCounters.resize(NestedLoopCount);
10284   Built.DependentInits.resize(NestedLoopCount);
10285   Built.FinalsConditions.resize(NestedLoopCount);
10286   {
10287     // We implement the following algorithm for obtaining the
10288     // original loop iteration variable values based on the
10289     // value of the collapsed loop iteration variable IV.
10290     //
10291     // Let n+1 be the number of collapsed loops in the nest.
10292     // Iteration variables (I0, I1, .... In)
10293     // Iteration counts (N0, N1, ... Nn)
10294     //
10295     // Acc = IV;
10296     //
10297     // To compute Ik for loop k, 0 <= k <= n, generate:
10298     //    Prod = N(k+1) * N(k+2) * ... * Nn;
10299     //    Ik = Acc / Prod;
10300     //    Acc -= Ik * Prod;
10301     //
10302     ExprResult Acc = IV;
10303     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10304       LoopIterationSpace &IS = IterSpaces[Cnt];
10305       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10306       ExprResult Iter;
10307 
10308       // Compute prod
10309       ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10310       for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10311         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10312                                   IterSpaces[K].NumIterations);
10313 
10314       // Iter = Acc / Prod
10315       // If there is at least one more inner loop to avoid
10316       // multiplication by 1.
10317       if (Cnt + 1 < NestedLoopCount)
10318         Iter =
10319             SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10320       else
10321         Iter = Acc;
10322       if (!Iter.isUsable()) {
10323         HasErrors = true;
10324         break;
10325       }
10326 
10327       // Update Acc:
10328       // Acc -= Iter * Prod
10329       // Check if there is at least one more inner loop to avoid
10330       // multiplication by 1.
10331       if (Cnt + 1 < NestedLoopCount)
10332         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10333                                   Prod.get());
10334       else
10335         Prod = Iter;
10336       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10337 
10338       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10339       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10340       DeclRefExpr *CounterVar = buildDeclRefExpr(
10341           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10342           /*RefersToCapture=*/true);
10343       ExprResult Init =
10344           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10345                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
10346       if (!Init.isUsable()) {
10347         HasErrors = true;
10348         break;
10349       }
10350       ExprResult Update = buildCounterUpdate(
10351           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10352           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10353       if (!Update.isUsable()) {
10354         HasErrors = true;
10355         break;
10356       }
10357 
10358       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10359       ExprResult Final =
10360           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10361                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
10362                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
10363       if (!Final.isUsable()) {
10364         HasErrors = true;
10365         break;
10366       }
10367 
10368       if (!Update.isUsable() || !Final.isUsable()) {
10369         HasErrors = true;
10370         break;
10371       }
10372       // Save results
10373       Built.Counters[Cnt] = IS.CounterVar;
10374       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10375       Built.Inits[Cnt] = Init.get();
10376       Built.Updates[Cnt] = Update.get();
10377       Built.Finals[Cnt] = Final.get();
10378       Built.DependentCounters[Cnt] = nullptr;
10379       Built.DependentInits[Cnt] = nullptr;
10380       Built.FinalsConditions[Cnt] = nullptr;
10381       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10382         Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1];
10383         Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1];
10384         Built.FinalsConditions[Cnt] = IS.FinalCondition;
10385       }
10386     }
10387   }
10388 
10389   if (HasErrors)
10390     return 0;
10391 
10392   // Save results
10393   Built.IterationVarRef = IV.get();
10394   Built.LastIteration = LastIteration.get();
10395   Built.NumIterations = NumIterations.get();
10396   Built.CalcLastIteration = SemaRef
10397                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
10398                                                      /*DiscardedValue=*/false)
10399                                 .get();
10400   Built.PreCond = PreCond.get();
10401   Built.PreInits = buildPreInits(C, Captures);
10402   Built.Cond = Cond.get();
10403   Built.Init = Init.get();
10404   Built.Inc = Inc.get();
10405   Built.LB = LB.get();
10406   Built.UB = UB.get();
10407   Built.IL = IL.get();
10408   Built.ST = ST.get();
10409   Built.EUB = EUB.get();
10410   Built.NLB = NextLB.get();
10411   Built.NUB = NextUB.get();
10412   Built.PrevLB = PrevLB.get();
10413   Built.PrevUB = PrevUB.get();
10414   Built.DistInc = DistInc.get();
10415   Built.PrevEUB = PrevEUB.get();
10416   Built.DistCombinedFields.LB = CombLB.get();
10417   Built.DistCombinedFields.UB = CombUB.get();
10418   Built.DistCombinedFields.EUB = CombEUB.get();
10419   Built.DistCombinedFields.Init = CombInit.get();
10420   Built.DistCombinedFields.Cond = CombCond.get();
10421   Built.DistCombinedFields.NLB = CombNextLB.get();
10422   Built.DistCombinedFields.NUB = CombNextUB.get();
10423   Built.DistCombinedFields.DistCond = CombDistCond.get();
10424   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10425 
10426   return NestedLoopCount;
10427 }
10428 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)10429 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10430   auto CollapseClauses =
10431       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10432   if (CollapseClauses.begin() != CollapseClauses.end())
10433     return (*CollapseClauses.begin())->getNumForLoops();
10434   return nullptr;
10435 }
10436 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)10437 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10438   auto OrderedClauses =
10439       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10440   if (OrderedClauses.begin() != OrderedClauses.end())
10441     return (*OrderedClauses.begin())->getNumForLoops();
10442   return nullptr;
10443 }
10444 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)10445 static bool checkSimdlenSafelenSpecified(Sema &S,
10446                                          const ArrayRef<OMPClause *> Clauses) {
10447   const OMPSafelenClause *Safelen = nullptr;
10448   const OMPSimdlenClause *Simdlen = nullptr;
10449 
10450   for (const OMPClause *Clause : Clauses) {
10451     if (Clause->getClauseKind() == OMPC_safelen)
10452       Safelen = cast<OMPSafelenClause>(Clause);
10453     else if (Clause->getClauseKind() == OMPC_simdlen)
10454       Simdlen = cast<OMPSimdlenClause>(Clause);
10455     if (Safelen && Simdlen)
10456       break;
10457   }
10458 
10459   if (Simdlen && Safelen) {
10460     const Expr *SimdlenLength = Simdlen->getSimdlen();
10461     const Expr *SafelenLength = Safelen->getSafelen();
10462     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10463         SimdlenLength->isInstantiationDependent() ||
10464         SimdlenLength->containsUnexpandedParameterPack())
10465       return false;
10466     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10467         SafelenLength->isInstantiationDependent() ||
10468         SafelenLength->containsUnexpandedParameterPack())
10469       return false;
10470     Expr::EvalResult SimdlenResult, SafelenResult;
10471     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10472     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10473     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10474     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10475     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10476     // If both simdlen and safelen clauses are specified, the value of the
10477     // simdlen parameter must be less than or equal to the value of the safelen
10478     // parameter.
10479     if (SimdlenRes > SafelenRes) {
10480       S.Diag(SimdlenLength->getExprLoc(),
10481              diag::err_omp_wrong_simdlen_safelen_values)
10482           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10483       return true;
10484     }
10485   }
10486   return false;
10487 }
10488 
10489 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10490                                         OpenMPDirectiveKind K,
10491                                         DSAStackTy *Stack);
10492 
checkLastPrivateForMappedDirectives(ArrayRef<OMPClause * > Clauses)10493 bool Sema::checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses) {
10494 
10495   // Check for syntax of lastprivate
10496   // Param of the lastprivate have different meanings in the mapped directives
10497   // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause
10498   //      "omp for"  lastprivate vars must be shared
10499   if (getLangOpts().OpenMP >= 50 &&
10500       DSAStack->getMappedDirective() == OMPD_loop &&
10501       checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) {
10502     return false;
10503   }
10504   return true;
10505 }
10506 
10507 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10508 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10509                                SourceLocation StartLoc, SourceLocation EndLoc,
10510                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10511   if (!AStmt)
10512     return StmtError();
10513 
10514   if (!checkLastPrivateForMappedDirectives(Clauses))
10515     return StmtError();
10516 
10517   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10518   OMPLoopBasedDirective::HelperExprs B;
10519   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10520   // define the nested loops number.
10521   unsigned NestedLoopCount = checkOpenMPLoop(
10522       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10523       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10524   if (NestedLoopCount == 0)
10525     return StmtError();
10526 
10527   assert((CurContext->isDependentContext() || B.builtAll()) &&
10528          "omp simd loop exprs were not built");
10529 
10530   if (!CurContext->isDependentContext()) {
10531     // Finalize the clauses that need pre-built expressions for CodeGen.
10532     for (OMPClause *C : Clauses) {
10533       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10534         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10535                                      B.NumIterations, *this, CurScope,
10536                                      DSAStack))
10537           return StmtError();
10538     }
10539   }
10540 
10541   if (checkSimdlenSafelenSpecified(*this, Clauses))
10542     return StmtError();
10543 
10544   setFunctionHasBranchProtectedScope();
10545   auto *SimdDirective = OMPSimdDirective::Create(
10546       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10547       DSAStack->getMappedDirective());
10548   return SimdDirective;
10549 }
10550 
10551 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10552 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10553                               SourceLocation StartLoc, SourceLocation EndLoc,
10554                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10555   if (!AStmt)
10556     return StmtError();
10557 
10558   if (!checkLastPrivateForMappedDirectives(Clauses))
10559     return StmtError();
10560 
10561   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10562   OMPLoopBasedDirective::HelperExprs B;
10563   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10564   // define the nested loops number.
10565   unsigned NestedLoopCount = checkOpenMPLoop(
10566       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10567       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10568   if (NestedLoopCount == 0)
10569     return StmtError();
10570 
10571   assert((CurContext->isDependentContext() || B.builtAll()) &&
10572          "omp for loop exprs were not built");
10573 
10574   if (!CurContext->isDependentContext()) {
10575     // Finalize the clauses that need pre-built expressions for CodeGen.
10576     for (OMPClause *C : Clauses) {
10577       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10578         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10579                                      B.NumIterations, *this, CurScope,
10580                                      DSAStack))
10581           return StmtError();
10582     }
10583   }
10584 
10585   auto *ForDirective = OMPForDirective::Create(
10586       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10587       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(),
10588       DSAStack->getMappedDirective());
10589   return ForDirective;
10590 }
10591 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10592 StmtResult Sema::ActOnOpenMPForSimdDirective(
10593     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10594     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10595   if (!AStmt)
10596     return StmtError();
10597 
10598   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10599   OMPLoopBasedDirective::HelperExprs B;
10600   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10601   // define the nested loops number.
10602   unsigned NestedLoopCount =
10603       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10604                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10605                       VarsWithImplicitDSA, B);
10606   if (NestedLoopCount == 0)
10607     return StmtError();
10608 
10609   assert((CurContext->isDependentContext() || B.builtAll()) &&
10610          "omp for simd loop exprs were not built");
10611 
10612   if (!CurContext->isDependentContext()) {
10613     // Finalize the clauses that need pre-built expressions for CodeGen.
10614     for (OMPClause *C : Clauses) {
10615       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10616         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10617                                      B.NumIterations, *this, CurScope,
10618                                      DSAStack))
10619           return StmtError();
10620     }
10621   }
10622 
10623   if (checkSimdlenSafelenSpecified(*this, Clauses))
10624     return StmtError();
10625 
10626   setFunctionHasBranchProtectedScope();
10627   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10628                                      Clauses, AStmt, B);
10629 }
10630 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10631 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10632                                               Stmt *AStmt,
10633                                               SourceLocation StartLoc,
10634                                               SourceLocation EndLoc) {
10635   if (!AStmt)
10636     return StmtError();
10637 
10638   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10639   auto BaseStmt = AStmt;
10640   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10641     BaseStmt = CS->getCapturedStmt();
10642   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10643     auto S = C->children();
10644     if (S.begin() == S.end())
10645       return StmtError();
10646     // All associated statements must be '#pragma omp section' except for
10647     // the first one.
10648     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10649       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10650         if (SectionStmt)
10651           Diag(SectionStmt->getBeginLoc(),
10652                diag::err_omp_sections_substmt_not_section);
10653         return StmtError();
10654       }
10655       cast<OMPSectionDirective>(SectionStmt)
10656           ->setHasCancel(DSAStack->isCancelRegion());
10657     }
10658   } else {
10659     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10660     return StmtError();
10661   }
10662 
10663   setFunctionHasBranchProtectedScope();
10664 
10665   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10666                                       DSAStack->getTaskgroupReductionRef(),
10667                                       DSAStack->isCancelRegion());
10668 }
10669 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10670 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10671                                              SourceLocation StartLoc,
10672                                              SourceLocation EndLoc) {
10673   if (!AStmt)
10674     return StmtError();
10675 
10676   setFunctionHasBranchProtectedScope();
10677   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10678 
10679   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10680                                      DSAStack->isCancelRegion());
10681 }
10682 
getDirectCallExpr(Expr * E)10683 static Expr *getDirectCallExpr(Expr *E) {
10684   E = E->IgnoreParenCasts()->IgnoreImplicit();
10685   if (auto *CE = dyn_cast<CallExpr>(E))
10686     if (CE->getDirectCallee())
10687       return E;
10688   return nullptr;
10689 }
10690 
ActOnOpenMPDispatchDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10691 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10692                                               Stmt *AStmt,
10693                                               SourceLocation StartLoc,
10694                                               SourceLocation EndLoc) {
10695   if (!AStmt)
10696     return StmtError();
10697 
10698   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10699 
10700   // 5.1 OpenMP
10701   // expression-stmt : an expression statement with one of the following forms:
10702   //   expression = target-call ( [expression-list] );
10703   //   target-call ( [expression-list] );
10704 
10705   SourceLocation TargetCallLoc;
10706 
10707   if (!CurContext->isDependentContext()) {
10708     Expr *TargetCall = nullptr;
10709 
10710     auto *E = dyn_cast<Expr>(S);
10711     if (!E) {
10712       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10713       return StmtError();
10714     }
10715 
10716     E = E->IgnoreParenCasts()->IgnoreImplicit();
10717 
10718     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10719       if (BO->getOpcode() == BO_Assign)
10720         TargetCall = getDirectCallExpr(BO->getRHS());
10721     } else {
10722       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10723         if (COCE->getOperator() == OO_Equal)
10724           TargetCall = getDirectCallExpr(COCE->getArg(1));
10725       if (!TargetCall)
10726         TargetCall = getDirectCallExpr(E);
10727     }
10728     if (!TargetCall) {
10729       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10730       return StmtError();
10731     }
10732     TargetCallLoc = TargetCall->getExprLoc();
10733   }
10734 
10735   setFunctionHasBranchProtectedScope();
10736 
10737   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10738                                       TargetCallLoc);
10739 }
10740 
checkGenericLoopLastprivate(Sema & S,ArrayRef<OMPClause * > Clauses,OpenMPDirectiveKind K,DSAStackTy * Stack)10741 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10742                                         OpenMPDirectiveKind K,
10743                                         DSAStackTy *Stack) {
10744   bool ErrorFound = false;
10745   for (OMPClause *C : Clauses) {
10746     if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10747       for (Expr *RefExpr : LPC->varlists()) {
10748         SourceLocation ELoc;
10749         SourceRange ERange;
10750         Expr *SimpleRefExpr = RefExpr;
10751         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10752         if (ValueDecl *D = Res.first) {
10753           auto &&Info = Stack->isLoopControlVariable(D);
10754           if (!Info.first) {
10755             S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10756                 << getOpenMPDirectiveName(K);
10757             ErrorFound = true;
10758           }
10759         }
10760       }
10761     }
10762   }
10763   return ErrorFound;
10764 }
10765 
ActOnOpenMPGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10766 StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10767     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10768     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10769   if (!AStmt)
10770     return StmtError();
10771 
10772   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10773   // A list item may not appear in a lastprivate clause unless it is the
10774   // loop iteration variable of a loop that is associated with the construct.
10775   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10776     return StmtError();
10777 
10778   auto *CS = cast<CapturedStmt>(AStmt);
10779   // 1.2.2 OpenMP Language Terminology
10780   // Structured block - An executable statement with a single entry at the
10781   // top and a single exit at the bottom.
10782   // The point of exit cannot be a branch out of the structured block.
10783   // longjmp() and throw() must not violate the entry/exit criteria.
10784   CS->getCapturedDecl()->setNothrow();
10785 
10786   OMPLoopDirective::HelperExprs B;
10787   // In presence of clause 'collapse', it will define the nested loops number.
10788   unsigned NestedLoopCount = checkOpenMPLoop(
10789       OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10790       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10791   if (NestedLoopCount == 0)
10792     return StmtError();
10793 
10794   assert((CurContext->isDependentContext() || B.builtAll()) &&
10795          "omp loop exprs were not built");
10796 
10797   setFunctionHasBranchProtectedScope();
10798   return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10799                                          NestedLoopCount, Clauses, AStmt, B);
10800 }
10801 
ActOnOpenMPTeamsGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10802 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10803     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10804     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10805   if (!AStmt)
10806     return StmtError();
10807 
10808   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10809   // A list item may not appear in a lastprivate clause unless it is the
10810   // loop iteration variable of a loop that is associated with the construct.
10811   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10812     return StmtError();
10813 
10814   auto *CS = cast<CapturedStmt>(AStmt);
10815   // 1.2.2 OpenMP Language Terminology
10816   // Structured block - An executable statement with a single entry at the
10817   // top and a single exit at the bottom.
10818   // The point of exit cannot be a branch out of the structured block.
10819   // longjmp() and throw() must not violate the entry/exit criteria.
10820   CS->getCapturedDecl()->setNothrow();
10821   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10822        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10823     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10824     // 1.2.2 OpenMP Language Terminology
10825     // Structured block - An executable statement with a single entry at the
10826     // top and a single exit at the bottom.
10827     // The point of exit cannot be a branch out of the structured block.
10828     // longjmp() and throw() must not violate the entry/exit criteria.
10829     CS->getCapturedDecl()->setNothrow();
10830   }
10831 
10832   OMPLoopDirective::HelperExprs B;
10833   // In presence of clause 'collapse', it will define the nested loops number.
10834   unsigned NestedLoopCount =
10835       checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10836                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10837                       VarsWithImplicitDSA, B);
10838   if (NestedLoopCount == 0)
10839     return StmtError();
10840 
10841   assert((CurContext->isDependentContext() || B.builtAll()) &&
10842          "omp loop exprs were not built");
10843 
10844   setFunctionHasBranchProtectedScope();
10845   DSAStack->setParentTeamsRegionLoc(StartLoc);
10846 
10847   return OMPTeamsGenericLoopDirective::Create(
10848       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10849 }
10850 
ActOnOpenMPTargetTeamsGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10851 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10852     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10853     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10854   if (!AStmt)
10855     return StmtError();
10856 
10857   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10858   // A list item may not appear in a lastprivate clause unless it is the
10859   // loop iteration variable of a loop that is associated with the construct.
10860   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10861                                   DSAStack))
10862     return StmtError();
10863 
10864   auto *CS = cast<CapturedStmt>(AStmt);
10865   // 1.2.2 OpenMP Language Terminology
10866   // Structured block - An executable statement with a single entry at the
10867   // top and a single exit at the bottom.
10868   // The point of exit cannot be a branch out of the structured block.
10869   // longjmp() and throw() must not violate the entry/exit criteria.
10870   CS->getCapturedDecl()->setNothrow();
10871   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10872        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10873     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10874     // 1.2.2 OpenMP Language Terminology
10875     // Structured block - An executable statement with a single entry at the
10876     // top and a single exit at the bottom.
10877     // The point of exit cannot be a branch out of the structured block.
10878     // longjmp() and throw() must not violate the entry/exit criteria.
10879     CS->getCapturedDecl()->setNothrow();
10880   }
10881 
10882   OMPLoopDirective::HelperExprs B;
10883   // In presence of clause 'collapse', it will define the nested loops number.
10884   unsigned NestedLoopCount =
10885       checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10886                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10887                       VarsWithImplicitDSA, B);
10888   if (NestedLoopCount == 0)
10889     return StmtError();
10890 
10891   assert((CurContext->isDependentContext() || B.builtAll()) &&
10892          "omp loop exprs were not built");
10893 
10894   setFunctionHasBranchProtectedScope();
10895 
10896   return OMPTargetTeamsGenericLoopDirective::Create(
10897       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10898 }
10899 
ActOnOpenMPParallelGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10900 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10901     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10902     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10903   if (!AStmt)
10904     return StmtError();
10905 
10906   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10907   // A list item may not appear in a lastprivate clause unless it is the
10908   // loop iteration variable of a loop that is associated with the construct.
10909   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10910     return StmtError();
10911 
10912   auto *CS = cast<CapturedStmt>(AStmt);
10913   // 1.2.2 OpenMP Language Terminology
10914   // Structured block - An executable statement with a single entry at the
10915   // top and a single exit at the bottom.
10916   // The point of exit cannot be a branch out of the structured block.
10917   // longjmp() and throw() must not violate the entry/exit criteria.
10918   CS->getCapturedDecl()->setNothrow();
10919   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10920        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10921     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10922     // 1.2.2 OpenMP Language Terminology
10923     // Structured block - An executable statement with a single entry at the
10924     // top and a single exit at the bottom.
10925     // The point of exit cannot be a branch out of the structured block.
10926     // longjmp() and throw() must not violate the entry/exit criteria.
10927     CS->getCapturedDecl()->setNothrow();
10928   }
10929 
10930   OMPLoopDirective::HelperExprs B;
10931   // In presence of clause 'collapse', it will define the nested loops number.
10932   unsigned NestedLoopCount =
10933       checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10934                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10935                       VarsWithImplicitDSA, B);
10936   if (NestedLoopCount == 0)
10937     return StmtError();
10938 
10939   assert((CurContext->isDependentContext() || B.builtAll()) &&
10940          "omp loop exprs were not built");
10941 
10942   setFunctionHasBranchProtectedScope();
10943 
10944   return OMPParallelGenericLoopDirective::Create(
10945       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10946 }
10947 
ActOnOpenMPTargetParallelGenericLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10948 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10949     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10950     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10951   if (!AStmt)
10952     return StmtError();
10953 
10954   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10955   // A list item may not appear in a lastprivate clause unless it is the
10956   // loop iteration variable of a loop that is associated with the construct.
10957   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10958                                   DSAStack))
10959     return StmtError();
10960 
10961   auto *CS = cast<CapturedStmt>(AStmt);
10962   // 1.2.2 OpenMP Language Terminology
10963   // Structured block - An executable statement with a single entry at the
10964   // top and a single exit at the bottom.
10965   // The point of exit cannot be a branch out of the structured block.
10966   // longjmp() and throw() must not violate the entry/exit criteria.
10967   CS->getCapturedDecl()->setNothrow();
10968   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10969        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10970     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10971     // 1.2.2 OpenMP Language Terminology
10972     // Structured block - An executable statement with a single entry at the
10973     // top and a single exit at the bottom.
10974     // The point of exit cannot be a branch out of the structured block.
10975     // longjmp() and throw() must not violate the entry/exit criteria.
10976     CS->getCapturedDecl()->setNothrow();
10977   }
10978 
10979   OMPLoopDirective::HelperExprs B;
10980   // In presence of clause 'collapse', it will define the nested loops number.
10981   unsigned NestedLoopCount =
10982       checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10983                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10984                       VarsWithImplicitDSA, B);
10985   if (NestedLoopCount == 0)
10986     return StmtError();
10987 
10988   assert((CurContext->isDependentContext() || B.builtAll()) &&
10989          "omp loop exprs were not built");
10990 
10991   setFunctionHasBranchProtectedScope();
10992 
10993   return OMPTargetParallelGenericLoopDirective::Create(
10994       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10995 }
10996 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10997 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10998                                             Stmt *AStmt,
10999                                             SourceLocation StartLoc,
11000                                             SourceLocation EndLoc) {
11001   if (!AStmt)
11002     return StmtError();
11003 
11004   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11005 
11006   setFunctionHasBranchProtectedScope();
11007 
11008   // OpenMP [2.7.3, single Construct, Restrictions]
11009   // The copyprivate clause must not be used with the nowait clause.
11010   const OMPClause *Nowait = nullptr;
11011   const OMPClause *Copyprivate = nullptr;
11012   for (const OMPClause *Clause : Clauses) {
11013     if (Clause->getClauseKind() == OMPC_nowait)
11014       Nowait = Clause;
11015     else if (Clause->getClauseKind() == OMPC_copyprivate)
11016       Copyprivate = Clause;
11017     if (Copyprivate && Nowait) {
11018       Diag(Copyprivate->getBeginLoc(),
11019            diag::err_omp_single_copyprivate_with_nowait);
11020       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
11021       return StmtError();
11022     }
11023   }
11024 
11025   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11026 }
11027 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11028 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
11029                                             SourceLocation StartLoc,
11030                                             SourceLocation EndLoc) {
11031   if (!AStmt)
11032     return StmtError();
11033 
11034   setFunctionHasBranchProtectedScope();
11035 
11036   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
11037 }
11038 
ActOnOpenMPMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11039 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
11040                                             Stmt *AStmt,
11041                                             SourceLocation StartLoc,
11042                                             SourceLocation EndLoc) {
11043   if (!AStmt)
11044     return StmtError();
11045 
11046   setFunctionHasBranchProtectedScope();
11047 
11048   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11049 }
11050 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11051 StmtResult Sema::ActOnOpenMPCriticalDirective(
11052     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
11053     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
11054   if (!AStmt)
11055     return StmtError();
11056 
11057   bool ErrorFound = false;
11058   llvm::APSInt Hint;
11059   SourceLocation HintLoc;
11060   bool DependentHint = false;
11061   for (const OMPClause *C : Clauses) {
11062     if (C->getClauseKind() == OMPC_hint) {
11063       if (!DirName.getName()) {
11064         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11065         ErrorFound = true;
11066       }
11067       Expr *E = cast<OMPHintClause>(C)->getHint();
11068       if (E->isTypeDependent() || E->isValueDependent() ||
11069           E->isInstantiationDependent()) {
11070         DependentHint = true;
11071       } else {
11072         Hint = E->EvaluateKnownConstInt(Context);
11073         HintLoc = C->getBeginLoc();
11074       }
11075     }
11076   }
11077   if (ErrorFound)
11078     return StmtError();
11079   const auto Pair = DSAStack->getCriticalWithHint(DirName);
11080   if (Pair.first && DirName.getName() && !DependentHint) {
11081     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11082       Diag(StartLoc, diag::err_omp_critical_with_hint);
11083       if (HintLoc.isValid())
11084         Diag(HintLoc, diag::note_omp_critical_hint_here)
11085             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
11086       else
11087         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11088       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
11089         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
11090             << 1
11091             << toString(C->getHint()->EvaluateKnownConstInt(Context),
11092                         /*Radix=*/10, /*Signed=*/false);
11093       } else {
11094         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11095       }
11096     }
11097   }
11098 
11099   setFunctionHasBranchProtectedScope();
11100 
11101   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
11102                                            Clauses, AStmt);
11103   if (!Pair.first && DirName.getName() && !DependentHint)
11104     DSAStack->addCriticalWithHint(Dir, Hint);
11105   return Dir;
11106 }
11107 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11108 StmtResult Sema::ActOnOpenMPParallelForDirective(
11109     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11110     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11111   if (!AStmt)
11112     return StmtError();
11113 
11114   auto *CS = cast<CapturedStmt>(AStmt);
11115   // 1.2.2 OpenMP Language Terminology
11116   // Structured block - An executable statement with a single entry at the
11117   // top and a single exit at the bottom.
11118   // The point of exit cannot be a branch out of the structured block.
11119   // longjmp() and throw() must not violate the entry/exit criteria.
11120   CS->getCapturedDecl()->setNothrow();
11121 
11122   OMPLoopBasedDirective::HelperExprs B;
11123   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11124   // define the nested loops number.
11125   unsigned NestedLoopCount =
11126       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
11127                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11128                       VarsWithImplicitDSA, B);
11129   if (NestedLoopCount == 0)
11130     return StmtError();
11131 
11132   assert((CurContext->isDependentContext() || B.builtAll()) &&
11133          "omp parallel for loop exprs were not built");
11134 
11135   if (!CurContext->isDependentContext()) {
11136     // Finalize the clauses that need pre-built expressions for CodeGen.
11137     for (OMPClause *C : Clauses) {
11138       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11139         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11140                                      B.NumIterations, *this, CurScope,
11141                                      DSAStack))
11142           return StmtError();
11143     }
11144   }
11145 
11146   setFunctionHasBranchProtectedScope();
11147   return OMPParallelForDirective::Create(
11148       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11149       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11150 }
11151 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11152 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
11153     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11154     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11155   if (!AStmt)
11156     return StmtError();
11157 
11158   auto *CS = cast<CapturedStmt>(AStmt);
11159   // 1.2.2 OpenMP Language Terminology
11160   // Structured block - An executable statement with a single entry at the
11161   // top and a single exit at the bottom.
11162   // The point of exit cannot be a branch out of the structured block.
11163   // longjmp() and throw() must not violate the entry/exit criteria.
11164   CS->getCapturedDecl()->setNothrow();
11165 
11166   OMPLoopBasedDirective::HelperExprs B;
11167   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11168   // define the nested loops number.
11169   unsigned NestedLoopCount =
11170       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
11171                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11172                       VarsWithImplicitDSA, B);
11173   if (NestedLoopCount == 0)
11174     return StmtError();
11175 
11176   if (!CurContext->isDependentContext()) {
11177     // Finalize the clauses that need pre-built expressions for CodeGen.
11178     for (OMPClause *C : Clauses) {
11179       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11180         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11181                                      B.NumIterations, *this, CurScope,
11182                                      DSAStack))
11183           return StmtError();
11184     }
11185   }
11186 
11187   if (checkSimdlenSafelenSpecified(*this, Clauses))
11188     return StmtError();
11189 
11190   setFunctionHasBranchProtectedScope();
11191   return OMPParallelForSimdDirective::Create(
11192       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11193 }
11194 
11195 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11196 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
11197                                          Stmt *AStmt, SourceLocation StartLoc,
11198                                          SourceLocation EndLoc) {
11199   if (!AStmt)
11200     return StmtError();
11201 
11202   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11203   auto *CS = cast<CapturedStmt>(AStmt);
11204   // 1.2.2 OpenMP Language Terminology
11205   // Structured block - An executable statement with a single entry at the
11206   // top and a single exit at the bottom.
11207   // The point of exit cannot be a branch out of the structured block.
11208   // longjmp() and throw() must not violate the entry/exit criteria.
11209   CS->getCapturedDecl()->setNothrow();
11210 
11211   setFunctionHasBranchProtectedScope();
11212 
11213   return OMPParallelMasterDirective::Create(
11214       Context, StartLoc, EndLoc, Clauses, AStmt,
11215       DSAStack->getTaskgroupReductionRef());
11216 }
11217 
11218 StmtResult
ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11219 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
11220                                          Stmt *AStmt, SourceLocation StartLoc,
11221                                          SourceLocation EndLoc) {
11222   if (!AStmt)
11223     return StmtError();
11224 
11225   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11226   auto *CS = cast<CapturedStmt>(AStmt);
11227   // 1.2.2 OpenMP Language Terminology
11228   // Structured block - An executable statement with a single entry at the
11229   // top and a single exit at the bottom.
11230   // The point of exit cannot be a branch out of the structured block.
11231   // longjmp() and throw() must not violate the entry/exit criteria.
11232   CS->getCapturedDecl()->setNothrow();
11233 
11234   setFunctionHasBranchProtectedScope();
11235 
11236   return OMPParallelMaskedDirective::Create(
11237       Context, StartLoc, EndLoc, Clauses, AStmt,
11238       DSAStack->getTaskgroupReductionRef());
11239 }
11240 
11241 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11242 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
11243                                            Stmt *AStmt, SourceLocation StartLoc,
11244                                            SourceLocation EndLoc) {
11245   if (!AStmt)
11246     return StmtError();
11247 
11248   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11249   auto BaseStmt = AStmt;
11250   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11251     BaseStmt = CS->getCapturedStmt();
11252   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11253     auto S = C->children();
11254     if (S.begin() == S.end())
11255       return StmtError();
11256     // All associated statements must be '#pragma omp section' except for
11257     // the first one.
11258     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
11259       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11260         if (SectionStmt)
11261           Diag(SectionStmt->getBeginLoc(),
11262                diag::err_omp_parallel_sections_substmt_not_section);
11263         return StmtError();
11264       }
11265       cast<OMPSectionDirective>(SectionStmt)
11266           ->setHasCancel(DSAStack->isCancelRegion());
11267     }
11268   } else {
11269     Diag(AStmt->getBeginLoc(),
11270          diag::err_omp_parallel_sections_not_compound_stmt);
11271     return StmtError();
11272   }
11273 
11274   setFunctionHasBranchProtectedScope();
11275 
11276   return OMPParallelSectionsDirective::Create(
11277       Context, StartLoc, EndLoc, Clauses, AStmt,
11278       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11279 }
11280 
11281 /// Find and diagnose mutually exclusive clause kinds.
checkMutuallyExclusiveClauses(Sema & S,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses)11282 static bool checkMutuallyExclusiveClauses(
11283     Sema &S, ArrayRef<OMPClause *> Clauses,
11284     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11285   const OMPClause *PrevClause = nullptr;
11286   bool ErrorFound = false;
11287   for (const OMPClause *C : Clauses) {
11288     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11289       if (!PrevClause) {
11290         PrevClause = C;
11291       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11292         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11293             << getOpenMPClauseName(C->getClauseKind())
11294             << getOpenMPClauseName(PrevClause->getClauseKind());
11295         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11296             << getOpenMPClauseName(PrevClause->getClauseKind());
11297         ErrorFound = true;
11298       }
11299     }
11300   }
11301   return ErrorFound;
11302 }
11303 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11304 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
11305                                           Stmt *AStmt, SourceLocation StartLoc,
11306                                           SourceLocation EndLoc) {
11307   if (!AStmt)
11308     return StmtError();
11309 
11310   // OpenMP 5.0, 2.10.1 task Construct
11311   // If a detach clause appears on the directive, then a mergeable clause cannot
11312   // appear on the same directive.
11313   if (checkMutuallyExclusiveClauses(*this, Clauses,
11314                                     {OMPC_detach, OMPC_mergeable}))
11315     return StmtError();
11316 
11317   auto *CS = cast<CapturedStmt>(AStmt);
11318   // 1.2.2 OpenMP Language Terminology
11319   // Structured block - An executable statement with a single entry at the
11320   // top and a single exit at the bottom.
11321   // The point of exit cannot be a branch out of the structured block.
11322   // longjmp() and throw() must not violate the entry/exit criteria.
11323   CS->getCapturedDecl()->setNothrow();
11324 
11325   setFunctionHasBranchProtectedScope();
11326 
11327   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11328                                   DSAStack->isCancelRegion());
11329 }
11330 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)11331 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11332                                                SourceLocation EndLoc) {
11333   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11334 }
11335 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)11336 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11337                                              SourceLocation EndLoc) {
11338   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11339 }
11340 
ActOnOpenMPErrorDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,bool InExContext)11341 StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11342                                            SourceLocation StartLoc,
11343                                            SourceLocation EndLoc,
11344                                            bool InExContext) {
11345   const OMPAtClause *AtC =
11346       OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11347 
11348   if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11349     Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11350     return StmtError();
11351   }
11352 
11353   const OMPSeverityClause *SeverityC =
11354       OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11355   const OMPMessageClause *MessageC =
11356       OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11357   Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11358 
11359   if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11360     if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11361       Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11362           << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11363     else
11364       Diag(StartLoc, diag::err_diagnose_if_succeeded)
11365           << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11366     if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11367       return StmtError();
11368   }
11369   return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11370 }
11371 
ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11372 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11373                                               SourceLocation StartLoc,
11374                                               SourceLocation EndLoc) {
11375   const OMPNowaitClause *NowaitC =
11376       OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11377   bool HasDependC =
11378       !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11379            .empty();
11380   if (NowaitC && !HasDependC) {
11381     Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11382     return StmtError();
11383   }
11384 
11385   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11386 }
11387 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11388 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11389                                                Stmt *AStmt,
11390                                                SourceLocation StartLoc,
11391                                                SourceLocation EndLoc) {
11392   if (!AStmt)
11393     return StmtError();
11394 
11395   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11396 
11397   setFunctionHasBranchProtectedScope();
11398 
11399   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11400                                        AStmt,
11401                                        DSAStack->getTaskgroupReductionRef());
11402 }
11403 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11404 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11405                                            SourceLocation StartLoc,
11406                                            SourceLocation EndLoc) {
11407   OMPFlushClause *FC = nullptr;
11408   OMPClause *OrderClause = nullptr;
11409   for (OMPClause *C : Clauses) {
11410     if (C->getClauseKind() == OMPC_flush)
11411       FC = cast<OMPFlushClause>(C);
11412     else
11413       OrderClause = C;
11414   }
11415   OpenMPClauseKind MemOrderKind = OMPC_unknown;
11416   SourceLocation MemOrderLoc;
11417   for (const OMPClause *C : Clauses) {
11418     if (C->getClauseKind() == OMPC_acq_rel ||
11419         C->getClauseKind() == OMPC_acquire ||
11420         C->getClauseKind() == OMPC_release) {
11421       if (MemOrderKind != OMPC_unknown) {
11422         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11423             << getOpenMPDirectiveName(OMPD_flush) << 1
11424             << SourceRange(C->getBeginLoc(), C->getEndLoc());
11425         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11426             << getOpenMPClauseName(MemOrderKind);
11427       } else {
11428         MemOrderKind = C->getClauseKind();
11429         MemOrderLoc = C->getBeginLoc();
11430       }
11431     }
11432   }
11433   if (FC && OrderClause) {
11434     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11435         << getOpenMPClauseName(OrderClause->getClauseKind());
11436     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11437         << getOpenMPClauseName(OrderClause->getClauseKind());
11438     return StmtError();
11439   }
11440   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11441 }
11442 
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11443 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11444                                             SourceLocation StartLoc,
11445                                             SourceLocation EndLoc) {
11446   if (Clauses.empty()) {
11447     Diag(StartLoc, diag::err_omp_depobj_expected);
11448     return StmtError();
11449   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11450     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11451     return StmtError();
11452   }
11453   // Only depobj expression and another single clause is allowed.
11454   if (Clauses.size() > 2) {
11455     Diag(Clauses[2]->getBeginLoc(),
11456          diag::err_omp_depobj_single_clause_expected);
11457     return StmtError();
11458   } else if (Clauses.size() < 1) {
11459     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11460     return StmtError();
11461   }
11462   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11463 }
11464 
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)11465 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11466                                           SourceLocation StartLoc,
11467                                           SourceLocation EndLoc) {
11468   // Check that exactly one clause is specified.
11469   if (Clauses.size() != 1) {
11470     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11471          diag::err_omp_scan_single_clause_expected);
11472     return StmtError();
11473   }
11474   // Check that scan directive is used in the scopeof the OpenMP loop body.
11475   if (Scope *S = DSAStack->getCurScope()) {
11476     Scope *ParentS = S->getParent();
11477     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11478         !ParentS->getBreakParent()->isOpenMPLoopScope())
11479       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11480                        << getOpenMPDirectiveName(OMPD_scan) << 5);
11481   }
11482   // Check that only one instance of scan directives is used in the same outer
11483   // region.
11484   if (DSAStack->doesParentHasScanDirective()) {
11485     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11486     Diag(DSAStack->getParentScanDirectiveLoc(),
11487          diag::note_omp_previous_directive)
11488         << "scan";
11489     return StmtError();
11490   }
11491   DSAStack->setParentHasScanDirective(StartLoc);
11492   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11493 }
11494 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11495 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11496                                              Stmt *AStmt,
11497                                              SourceLocation StartLoc,
11498                                              SourceLocation EndLoc) {
11499   const OMPClause *DependFound = nullptr;
11500   const OMPClause *DependSourceClause = nullptr;
11501   const OMPClause *DependSinkClause = nullptr;
11502   const OMPClause *DoacrossFound = nullptr;
11503   const OMPClause *DoacrossSourceClause = nullptr;
11504   const OMPClause *DoacrossSinkClause = nullptr;
11505   bool ErrorFound = false;
11506   const OMPThreadsClause *TC = nullptr;
11507   const OMPSIMDClause *SC = nullptr;
11508   for (const OMPClause *C : Clauses) {
11509     auto DOC = dyn_cast<OMPDoacrossClause>(C);
11510     auto DC = dyn_cast<OMPDependClause>(C);
11511     if (DC || DOC) {
11512       DependFound = DC ? C : nullptr;
11513       DoacrossFound = DOC ? C : nullptr;
11514       OMPDoacrossKind ODK;
11515       if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11516           (DOC && (ODK.isSource(DOC)))) {
11517         if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11518           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11519               << getOpenMPDirectiveName(OMPD_ordered)
11520               << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11521           ErrorFound = true;
11522         } else {
11523           if (DC)
11524             DependSourceClause = C;
11525           else
11526             DoacrossSourceClause = C;
11527         }
11528         if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11529           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11530               << (DC ? "depend" : "doacross") << 0;
11531           ErrorFound = true;
11532         }
11533       } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11534                  (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11535         if (DependSourceClause || DoacrossSourceClause) {
11536           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11537               << (DC ? "depend" : "doacross") << 1;
11538           ErrorFound = true;
11539         }
11540         if (DC)
11541           DependSinkClause = C;
11542         else
11543           DoacrossSinkClause = C;
11544       }
11545     } else if (C->getClauseKind() == OMPC_threads) {
11546       TC = cast<OMPThreadsClause>(C);
11547     } else if (C->getClauseKind() == OMPC_simd) {
11548       SC = cast<OMPSIMDClause>(C);
11549     }
11550   }
11551   if (!ErrorFound && !SC &&
11552       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11553     // OpenMP [2.8.1,simd Construct, Restrictions]
11554     // An ordered construct with the simd clause is the only OpenMP construct
11555     // that can appear in the simd region.
11556     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11557         << (LangOpts.OpenMP >= 50 ? 1 : 0);
11558     ErrorFound = true;
11559   } else if ((DependFound || DoacrossFound) && (TC || SC)) {
11560     SourceLocation Loc =
11561         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11562     Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11563         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11564         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11565     ErrorFound = true;
11566   } else if ((DependFound || DoacrossFound) &&
11567              !DSAStack->getParentOrderedRegionParam().first) {
11568     SourceLocation Loc =
11569         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11570     Diag(Loc, diag::err_omp_ordered_directive_without_param)
11571         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11572     ErrorFound = true;
11573   } else if (TC || Clauses.empty()) {
11574     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11575       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11576       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11577           << (TC != nullptr);
11578       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11579       ErrorFound = true;
11580     }
11581   }
11582   if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11583     return StmtError();
11584 
11585   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11586   // During execution of an iteration of a worksharing-loop or a loop nest
11587   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11588   // must not execute more than one ordered region corresponding to an ordered
11589   // construct without a depend clause.
11590   if (!DependFound && !DoacrossFound) {
11591     if (DSAStack->doesParentHasOrderedDirective()) {
11592       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11593       Diag(DSAStack->getParentOrderedDirectiveLoc(),
11594            diag::note_omp_previous_directive)
11595           << "ordered";
11596       return StmtError();
11597     }
11598     DSAStack->setParentHasOrderedDirective(StartLoc);
11599   }
11600 
11601   if (AStmt) {
11602     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11603 
11604     setFunctionHasBranchProtectedScope();
11605   }
11606 
11607   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11608 }
11609 
11610 namespace {
11611 /// Helper class for checking expression in 'omp atomic [update]'
11612 /// construct.
11613 class OpenMPAtomicUpdateChecker {
11614   /// Error results for atomic update expressions.
11615   enum ExprAnalysisErrorCode {
11616     /// A statement is not an expression statement.
11617     NotAnExpression,
11618     /// Expression is not builtin binary or unary operation.
11619     NotABinaryOrUnaryExpression,
11620     /// Unary operation is not post-/pre- increment/decrement operation.
11621     NotAnUnaryIncDecExpression,
11622     /// An expression is not of scalar type.
11623     NotAScalarType,
11624     /// A binary operation is not an assignment operation.
11625     NotAnAssignmentOp,
11626     /// RHS part of the binary operation is not a binary expression.
11627     NotABinaryExpression,
11628     /// RHS part is not additive/multiplicative/shift/biwise binary
11629     /// expression.
11630     NotABinaryOperator,
11631     /// RHS binary operation does not have reference to the updated LHS
11632     /// part.
11633     NotAnUpdateExpression,
11634     /// An expression contains semantical error not related to
11635     /// 'omp atomic [update]'
11636     NotAValidExpression,
11637     /// No errors is found.
11638     NoError
11639   };
11640   /// Reference to Sema.
11641   Sema &SemaRef;
11642   /// A location for note diagnostics (when error is found).
11643   SourceLocation NoteLoc;
11644   /// 'x' lvalue part of the source atomic expression.
11645   Expr *X;
11646   /// 'expr' rvalue part of the source atomic expression.
11647   Expr *E;
11648   /// Helper expression of the form
11649   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11650   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11651   Expr *UpdateExpr;
11652   /// Is 'x' a LHS in a RHS part of full update expression. It is
11653   /// important for non-associative operations.
11654   bool IsXLHSInRHSPart;
11655   BinaryOperatorKind Op;
11656   SourceLocation OpLoc;
11657   /// true if the source expression is a postfix unary operation, false
11658   /// if it is a prefix unary operation.
11659   bool IsPostfixUpdate;
11660 
11661 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)11662   OpenMPAtomicUpdateChecker(Sema &SemaRef)
11663       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11664         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11665   /// Check specified statement that it is suitable for 'atomic update'
11666   /// constructs and extract 'x', 'expr' and Operation from the original
11667   /// expression. If DiagId and NoteId == 0, then only check is performed
11668   /// without error notification.
11669   /// \param DiagId Diagnostic which should be emitted if error is found.
11670   /// \param NoteId Diagnostic note for the main error message.
11671   /// \return true if statement is not an update expression, false otherwise.
11672   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11673   /// Return the 'x' lvalue part of the source atomic expression.
getX() const11674   Expr *getX() const { return X; }
11675   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const11676   Expr *getExpr() const { return E; }
11677   /// Return the update expression used in calculation of the updated
11678   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11679   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const11680   Expr *getUpdateExpr() const { return UpdateExpr; }
11681   /// Return true if 'x' is LHS in RHS part of full update expression,
11682   /// false otherwise.
isXLHSInRHSPart() const11683   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11684 
11685   /// true if the source expression is a postfix unary operation, false
11686   /// if it is a prefix unary operation.
isPostfixUpdate() const11687   bool isPostfixUpdate() const { return IsPostfixUpdate; }
11688 
11689 private:
11690   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11691                             unsigned NoteId = 0);
11692 };
11693 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)11694 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11695     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11696   ExprAnalysisErrorCode ErrorFound = NoError;
11697   SourceLocation ErrorLoc, NoteLoc;
11698   SourceRange ErrorRange, NoteRange;
11699   // Allowed constructs are:
11700   //  x = x binop expr;
11701   //  x = expr binop x;
11702   if (AtomicBinOp->getOpcode() == BO_Assign) {
11703     X = AtomicBinOp->getLHS();
11704     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11705             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11706       if (AtomicInnerBinOp->isMultiplicativeOp() ||
11707           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11708           AtomicInnerBinOp->isBitwiseOp()) {
11709         Op = AtomicInnerBinOp->getOpcode();
11710         OpLoc = AtomicInnerBinOp->getOperatorLoc();
11711         Expr *LHS = AtomicInnerBinOp->getLHS();
11712         Expr *RHS = AtomicInnerBinOp->getRHS();
11713         llvm::FoldingSetNodeID XId, LHSId, RHSId;
11714         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11715                                           /*Canonical=*/true);
11716         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11717                                             /*Canonical=*/true);
11718         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11719                                             /*Canonical=*/true);
11720         if (XId == LHSId) {
11721           E = RHS;
11722           IsXLHSInRHSPart = true;
11723         } else if (XId == RHSId) {
11724           E = LHS;
11725           IsXLHSInRHSPart = false;
11726         } else {
11727           ErrorLoc = AtomicInnerBinOp->getExprLoc();
11728           ErrorRange = AtomicInnerBinOp->getSourceRange();
11729           NoteLoc = X->getExprLoc();
11730           NoteRange = X->getSourceRange();
11731           ErrorFound = NotAnUpdateExpression;
11732         }
11733       } else {
11734         ErrorLoc = AtomicInnerBinOp->getExprLoc();
11735         ErrorRange = AtomicInnerBinOp->getSourceRange();
11736         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11737         NoteRange = SourceRange(NoteLoc, NoteLoc);
11738         ErrorFound = NotABinaryOperator;
11739       }
11740     } else {
11741       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11742       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11743       ErrorFound = NotABinaryExpression;
11744     }
11745   } else {
11746     ErrorLoc = AtomicBinOp->getExprLoc();
11747     ErrorRange = AtomicBinOp->getSourceRange();
11748     NoteLoc = AtomicBinOp->getOperatorLoc();
11749     NoteRange = SourceRange(NoteLoc, NoteLoc);
11750     ErrorFound = NotAnAssignmentOp;
11751   }
11752   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11753     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11754     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11755     return true;
11756   }
11757   if (SemaRef.CurContext->isDependentContext())
11758     E = X = UpdateExpr = nullptr;
11759   return ErrorFound != NoError;
11760 }
11761 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)11762 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11763                                                unsigned NoteId) {
11764   ExprAnalysisErrorCode ErrorFound = NoError;
11765   SourceLocation ErrorLoc, NoteLoc;
11766   SourceRange ErrorRange, NoteRange;
11767   // Allowed constructs are:
11768   //  x++;
11769   //  x--;
11770   //  ++x;
11771   //  --x;
11772   //  x binop= expr;
11773   //  x = x binop expr;
11774   //  x = expr binop x;
11775   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11776     AtomicBody = AtomicBody->IgnoreParenImpCasts();
11777     if (AtomicBody->getType()->isScalarType() ||
11778         AtomicBody->isInstantiationDependent()) {
11779       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11780               AtomicBody->IgnoreParenImpCasts())) {
11781         // Check for Compound Assignment Operation
11782         Op = BinaryOperator::getOpForCompoundAssignment(
11783             AtomicCompAssignOp->getOpcode());
11784         OpLoc = AtomicCompAssignOp->getOperatorLoc();
11785         E = AtomicCompAssignOp->getRHS();
11786         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11787         IsXLHSInRHSPart = true;
11788       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11789                      AtomicBody->IgnoreParenImpCasts())) {
11790         // Check for Binary Operation
11791         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11792           return true;
11793       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11794                      AtomicBody->IgnoreParenImpCasts())) {
11795         // Check for Unary Operation
11796         if (AtomicUnaryOp->isIncrementDecrementOp()) {
11797           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11798           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11799           OpLoc = AtomicUnaryOp->getOperatorLoc();
11800           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11801           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11802           IsXLHSInRHSPart = true;
11803         } else {
11804           ErrorFound = NotAnUnaryIncDecExpression;
11805           ErrorLoc = AtomicUnaryOp->getExprLoc();
11806           ErrorRange = AtomicUnaryOp->getSourceRange();
11807           NoteLoc = AtomicUnaryOp->getOperatorLoc();
11808           NoteRange = SourceRange(NoteLoc, NoteLoc);
11809         }
11810       } else if (!AtomicBody->isInstantiationDependent()) {
11811         ErrorFound = NotABinaryOrUnaryExpression;
11812         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11813         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11814       } else if (AtomicBody->containsErrors()) {
11815         ErrorFound = NotAValidExpression;
11816         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11817         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11818       }
11819     } else {
11820       ErrorFound = NotAScalarType;
11821       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11822       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11823     }
11824   } else {
11825     ErrorFound = NotAnExpression;
11826     NoteLoc = ErrorLoc = S->getBeginLoc();
11827     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11828   }
11829   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11830     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11831     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11832     return true;
11833   }
11834   if (SemaRef.CurContext->isDependentContext())
11835     E = X = UpdateExpr = nullptr;
11836   if (ErrorFound == NoError && E && X) {
11837     // Build an update expression of form 'OpaqueValueExpr(x) binop
11838     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11839     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11840     auto *OVEX = new (SemaRef.getASTContext())
11841         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11842     auto *OVEExpr = new (SemaRef.getASTContext())
11843         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11844     ExprResult Update =
11845         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11846                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
11847     if (Update.isInvalid())
11848       return true;
11849     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11850                                                Sema::AA_Casting);
11851     if (Update.isInvalid())
11852       return true;
11853     UpdateExpr = Update.get();
11854   }
11855   return ErrorFound != NoError;
11856 }
11857 
11858 /// Get the node id of the fixed point of an expression \a S.
getNodeId(ASTContext & Context,const Expr * S)11859 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11860   llvm::FoldingSetNodeID Id;
11861   S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11862   return Id;
11863 }
11864 
11865 /// Check if two expressions are same.
checkIfTwoExprsAreSame(ASTContext & Context,const Expr * LHS,const Expr * RHS)11866 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11867                             const Expr *RHS) {
11868   return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11869 }
11870 
11871 class OpenMPAtomicCompareChecker {
11872 public:
11873   /// All kinds of errors that can occur in `atomic compare`
11874   enum ErrorTy {
11875     /// Empty compound statement.
11876     NoStmt = 0,
11877     /// More than one statement in a compound statement.
11878     MoreThanOneStmt,
11879     /// Not an assignment binary operator.
11880     NotAnAssignment,
11881     /// Not a conditional operator.
11882     NotCondOp,
11883     /// Wrong false expr. According to the spec, 'x' should be at the false
11884     /// expression of a conditional expression.
11885     WrongFalseExpr,
11886     /// The condition of a conditional expression is not a binary operator.
11887     NotABinaryOp,
11888     /// Invalid binary operator (not <, >, or ==).
11889     InvalidBinaryOp,
11890     /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11891     InvalidComparison,
11892     /// X is not a lvalue.
11893     XNotLValue,
11894     /// Not a scalar.
11895     NotScalar,
11896     /// Not an integer.
11897     NotInteger,
11898     /// 'else' statement is not expected.
11899     UnexpectedElse,
11900     /// Not an equality operator.
11901     NotEQ,
11902     /// Invalid assignment (not v == x).
11903     InvalidAssignment,
11904     /// Not if statement
11905     NotIfStmt,
11906     /// More than two statements in a compund statement.
11907     MoreThanTwoStmts,
11908     /// Not a compound statement.
11909     NotCompoundStmt,
11910     /// No else statement.
11911     NoElse,
11912     /// Not 'if (r)'.
11913     InvalidCondition,
11914     /// No error.
11915     NoError,
11916   };
11917 
11918   struct ErrorInfoTy {
11919     ErrorTy Error;
11920     SourceLocation ErrorLoc;
11921     SourceRange ErrorRange;
11922     SourceLocation NoteLoc;
11923     SourceRange NoteRange;
11924   };
11925 
OpenMPAtomicCompareChecker(Sema & S)11926   OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11927 
11928   /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11929   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11930 
getX() const11931   Expr *getX() const { return X; }
getE() const11932   Expr *getE() const { return E; }
getD() const11933   Expr *getD() const { return D; }
getCond() const11934   Expr *getCond() const { return C; }
isXBinopExpr() const11935   bool isXBinopExpr() const { return IsXBinopExpr; }
11936 
11937 protected:
11938   /// Reference to ASTContext
11939   ASTContext &ContextRef;
11940   /// 'x' lvalue part of the source atomic expression.
11941   Expr *X = nullptr;
11942   /// 'expr' or 'e' rvalue part of the source atomic expression.
11943   Expr *E = nullptr;
11944   /// 'd' rvalue part of the source atomic expression.
11945   Expr *D = nullptr;
11946   /// 'cond' part of the source atomic expression. It is in one of the following
11947   /// forms:
11948   /// expr ordop x
11949   /// x ordop expr
11950   /// x == e
11951   /// e == x
11952   Expr *C = nullptr;
11953   /// True if the cond expr is in the form of 'x ordop expr'.
11954   bool IsXBinopExpr = true;
11955 
11956   /// Check if it is a valid conditional update statement (cond-update-stmt).
11957   bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11958 
11959   /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11960   bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11961 
11962   /// Check if all captured values have right type.
11963   bool checkType(ErrorInfoTy &ErrorInfo) const;
11964 
CheckValue(const Expr * E,ErrorInfoTy & ErrorInfo,bool ShouldBeLValue,bool ShouldBeInteger=false)11965   static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11966                          bool ShouldBeLValue, bool ShouldBeInteger = false) {
11967     if (E->isInstantiationDependent())
11968       return true;
11969 
11970     if (ShouldBeLValue && !E->isLValue()) {
11971       ErrorInfo.Error = ErrorTy::XNotLValue;
11972       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11973       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11974       return false;
11975     }
11976 
11977     QualType QTy = E->getType();
11978     if (!QTy->isScalarType()) {
11979       ErrorInfo.Error = ErrorTy::NotScalar;
11980       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11981       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11982       return false;
11983     }
11984     if (ShouldBeInteger && !QTy->isIntegerType()) {
11985       ErrorInfo.Error = ErrorTy::NotInteger;
11986       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11987       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11988       return false;
11989     }
11990 
11991     return true;
11992   }
11993   };
11994 
checkCondUpdateStmt(IfStmt * S,ErrorInfoTy & ErrorInfo)11995 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11996                                                      ErrorInfoTy &ErrorInfo) {
11997   auto *Then = S->getThen();
11998   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11999     if (CS->body_empty()) {
12000       ErrorInfo.Error = ErrorTy::NoStmt;
12001       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12002       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12003       return false;
12004     }
12005     if (CS->size() > 1) {
12006       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12007       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12008       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12009       return false;
12010     }
12011     Then = CS->body_front();
12012   }
12013 
12014   auto *BO = dyn_cast<BinaryOperator>(Then);
12015   if (!BO) {
12016     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12017     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12018     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12019     return false;
12020   }
12021   if (BO->getOpcode() != BO_Assign) {
12022     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12023     ErrorInfo.ErrorLoc = BO->getExprLoc();
12024     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12025     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12026     return false;
12027   }
12028 
12029   X = BO->getLHS();
12030 
12031   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12032   if (!Cond) {
12033     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12034     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12035     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12036     return false;
12037   }
12038 
12039   switch (Cond->getOpcode()) {
12040   case BO_EQ: {
12041     C = Cond;
12042     D = BO->getRHS();
12043     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12044       E = Cond->getRHS();
12045     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12046       E = Cond->getLHS();
12047     } else {
12048       ErrorInfo.Error = ErrorTy::InvalidComparison;
12049       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12050       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12051       return false;
12052     }
12053     break;
12054   }
12055   case BO_LT:
12056   case BO_GT: {
12057     E = BO->getRHS();
12058     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12059         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12060       C = Cond;
12061     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12062                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12063       C = Cond;
12064       IsXBinopExpr = false;
12065     } else {
12066       ErrorInfo.Error = ErrorTy::InvalidComparison;
12067       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12068       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12069       return false;
12070     }
12071     break;
12072   }
12073   default:
12074     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12075     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12076     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12077     return false;
12078   }
12079 
12080   if (S->getElse()) {
12081     ErrorInfo.Error = ErrorTy::UnexpectedElse;
12082     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12083     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12084     return false;
12085   }
12086 
12087   return true;
12088 }
12089 
checkCondExprStmt(Stmt * S,ErrorInfoTy & ErrorInfo)12090 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
12091                                                    ErrorInfoTy &ErrorInfo) {
12092   auto *BO = dyn_cast<BinaryOperator>(S);
12093   if (!BO) {
12094     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12095     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12096     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12097     return false;
12098   }
12099   if (BO->getOpcode() != BO_Assign) {
12100     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12101     ErrorInfo.ErrorLoc = BO->getExprLoc();
12102     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12103     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12104     return false;
12105   }
12106 
12107   X = BO->getLHS();
12108 
12109   auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12110   if (!CO) {
12111     ErrorInfo.Error = ErrorTy::NotCondOp;
12112     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12113     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12114     return false;
12115   }
12116 
12117   if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
12118     ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12119     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12120     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12121         CO->getFalseExpr()->getSourceRange();
12122     return false;
12123   }
12124 
12125   auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12126   if (!Cond) {
12127     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12128     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12129     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12130         CO->getCond()->getSourceRange();
12131     return false;
12132   }
12133 
12134   switch (Cond->getOpcode()) {
12135   case BO_EQ: {
12136     C = Cond;
12137     D = CO->getTrueExpr();
12138     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12139       E = Cond->getRHS();
12140     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12141       E = Cond->getLHS();
12142     } else {
12143       ErrorInfo.Error = ErrorTy::InvalidComparison;
12144       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12145       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12146       return false;
12147     }
12148     break;
12149   }
12150   case BO_LT:
12151   case BO_GT: {
12152     E = CO->getTrueExpr();
12153     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12154         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12155       C = Cond;
12156     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12157                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12158       C = Cond;
12159       IsXBinopExpr = false;
12160     } else {
12161       ErrorInfo.Error = ErrorTy::InvalidComparison;
12162       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12163       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12164       return false;
12165     }
12166     break;
12167   }
12168   default:
12169     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12170     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12171     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12172     return false;
12173   }
12174 
12175   return true;
12176 }
12177 
checkType(ErrorInfoTy & ErrorInfo) const12178 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
12179   // 'x' and 'e' cannot be nullptr
12180   assert(X && E && "X and E cannot be nullptr");
12181 
12182   if (!CheckValue(X, ErrorInfo, true))
12183     return false;
12184 
12185   if (!CheckValue(E, ErrorInfo, false))
12186     return false;
12187 
12188   if (D && !CheckValue(D, ErrorInfo, false))
12189     return false;
12190 
12191   return true;
12192 }
12193 
checkStmt(Stmt * S,OpenMPAtomicCompareChecker::ErrorInfoTy & ErrorInfo)12194 bool OpenMPAtomicCompareChecker::checkStmt(
12195     Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12196   auto *CS = dyn_cast<CompoundStmt>(S);
12197   if (CS) {
12198     if (CS->body_empty()) {
12199       ErrorInfo.Error = ErrorTy::NoStmt;
12200       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12201       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12202       return false;
12203     }
12204 
12205     if (CS->size() != 1) {
12206       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12207       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12208       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12209       return false;
12210     }
12211     S = CS->body_front();
12212   }
12213 
12214   auto Res = false;
12215 
12216   if (auto *IS = dyn_cast<IfStmt>(S)) {
12217     // Check if the statement is in one of the following forms
12218     // (cond-update-stmt):
12219     // if (expr ordop x) { x = expr; }
12220     // if (x ordop expr) { x = expr; }
12221     // if (x == e) { x = d; }
12222     Res = checkCondUpdateStmt(IS, ErrorInfo);
12223   } else {
12224     // Check if the statement is in one of the following forms (cond-expr-stmt):
12225     // x = expr ordop x ? expr : x;
12226     // x = x ordop expr ? expr : x;
12227     // x = x == e ? d : x;
12228     Res = checkCondExprStmt(S, ErrorInfo);
12229   }
12230 
12231   if (!Res)
12232     return false;
12233 
12234   return checkType(ErrorInfo);
12235 }
12236 
12237 class OpenMPAtomicCompareCaptureChecker final
12238     : public OpenMPAtomicCompareChecker {
12239 public:
OpenMPAtomicCompareCaptureChecker(Sema & S)12240   OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
12241 
getV() const12242   Expr *getV() const { return V; }
getR() const12243   Expr *getR() const { return R; }
isFailOnly() const12244   bool isFailOnly() const { return IsFailOnly; }
isPostfixUpdate() const12245   bool isPostfixUpdate() const { return IsPostfixUpdate; }
12246 
12247   /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
12248   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
12249 
12250 private:
12251   bool checkType(ErrorInfoTy &ErrorInfo);
12252 
12253   // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
12254   // form of 'conditional-update-capture-atomic' structured block on the v5.2
12255   // spec p.p. 82:
12256   // (1) { v = x; cond-update-stmt }
12257   // (2) { cond-update-stmt v = x; }
12258   // (3) if(x == e) { x = d; } else { v = x; }
12259   // (4) { r = x == e; if(r) { x = d; } }
12260   // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
12261 
12262   /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
12263   bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
12264 
12265   /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
12266   /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
12267   bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
12268 
12269   /// 'v' lvalue part of the source atomic expression.
12270   Expr *V = nullptr;
12271   /// 'r' lvalue part of the source atomic expression.
12272   Expr *R = nullptr;
12273   /// If 'v' is only updated when the comparison fails.
12274   bool IsFailOnly = false;
12275   /// If original value of 'x' must be stored in 'v', not an updated one.
12276   bool IsPostfixUpdate = false;
12277 };
12278 
checkType(ErrorInfoTy & ErrorInfo)12279 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12280   if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12281     return false;
12282 
12283   if (V && !CheckValue(V, ErrorInfo, true))
12284     return false;
12285 
12286   if (R && !CheckValue(R, ErrorInfo, true, true))
12287     return false;
12288 
12289   return true;
12290 }
12291 
checkForm3(IfStmt * S,ErrorInfoTy & ErrorInfo)12292 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
12293                                                    ErrorInfoTy &ErrorInfo) {
12294   IsFailOnly = true;
12295 
12296   auto *Then = S->getThen();
12297   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
12298     if (CS->body_empty()) {
12299       ErrorInfo.Error = ErrorTy::NoStmt;
12300       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12301       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12302       return false;
12303     }
12304     if (CS->size() > 1) {
12305       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12306       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12307       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12308       return false;
12309     }
12310     Then = CS->body_front();
12311   }
12312 
12313   auto *BO = dyn_cast<BinaryOperator>(Then);
12314   if (!BO) {
12315     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12316     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12317     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12318     return false;
12319   }
12320   if (BO->getOpcode() != BO_Assign) {
12321     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12322     ErrorInfo.ErrorLoc = BO->getExprLoc();
12323     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12324     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12325     return false;
12326   }
12327 
12328   X = BO->getLHS();
12329   D = BO->getRHS();
12330 
12331   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12332   if (!Cond) {
12333     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12334     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12335     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12336     return false;
12337   }
12338   if (Cond->getOpcode() != BO_EQ) {
12339     ErrorInfo.Error = ErrorTy::NotEQ;
12340     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12341     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12342     return false;
12343   }
12344 
12345   if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12346     E = Cond->getRHS();
12347   } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12348     E = Cond->getLHS();
12349   } else {
12350     ErrorInfo.Error = ErrorTy::InvalidComparison;
12351     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12352     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12353     return false;
12354   }
12355 
12356   C = Cond;
12357 
12358   if (!S->getElse()) {
12359     ErrorInfo.Error = ErrorTy::NoElse;
12360     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12361     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12362     return false;
12363   }
12364 
12365   auto *Else = S->getElse();
12366   if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12367     if (CS->body_empty()) {
12368       ErrorInfo.Error = ErrorTy::NoStmt;
12369       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12370       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12371       return false;
12372     }
12373     if (CS->size() > 1) {
12374       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12375       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12376       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12377       return false;
12378     }
12379     Else = CS->body_front();
12380   }
12381 
12382   auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12383   if (!ElseBO) {
12384     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12385     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12386     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12387     return false;
12388   }
12389   if (ElseBO->getOpcode() != BO_Assign) {
12390     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12391     ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12392     ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12393     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12394     return false;
12395   }
12396 
12397   if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12398     ErrorInfo.Error = ErrorTy::InvalidAssignment;
12399     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12400     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12401         ElseBO->getRHS()->getSourceRange();
12402     return false;
12403   }
12404 
12405   V = ElseBO->getLHS();
12406 
12407   return checkType(ErrorInfo);
12408 }
12409 
checkForm45(Stmt * S,ErrorInfoTy & ErrorInfo)12410 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12411                                                     ErrorInfoTy &ErrorInfo) {
12412   // We don't check here as they should be already done before call this
12413   // function.
12414   auto *CS = cast<CompoundStmt>(S);
12415   assert(CS->size() == 2 && "CompoundStmt size is not expected");
12416   auto *S1 = cast<BinaryOperator>(CS->body_front());
12417   auto *S2 = cast<IfStmt>(CS->body_back());
12418   assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12419 
12420   if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12421     ErrorInfo.Error = ErrorTy::InvalidCondition;
12422     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12423     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12424     return false;
12425   }
12426 
12427   R = S1->getLHS();
12428 
12429   auto *Then = S2->getThen();
12430   if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12431     if (ThenCS->body_empty()) {
12432       ErrorInfo.Error = ErrorTy::NoStmt;
12433       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12434       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12435       return false;
12436     }
12437     if (ThenCS->size() > 1) {
12438       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12439       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12440       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12441       return false;
12442     }
12443     Then = ThenCS->body_front();
12444   }
12445 
12446   auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12447   if (!ThenBO) {
12448     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12449     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12450     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12451     return false;
12452   }
12453   if (ThenBO->getOpcode() != BO_Assign) {
12454     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12455     ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12456     ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12457     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12458     return false;
12459   }
12460 
12461   X = ThenBO->getLHS();
12462   D = ThenBO->getRHS();
12463 
12464   auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12465   if (BO->getOpcode() != BO_EQ) {
12466     ErrorInfo.Error = ErrorTy::NotEQ;
12467     ErrorInfo.ErrorLoc = BO->getExprLoc();
12468     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12469     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12470     return false;
12471   }
12472 
12473   C = BO;
12474 
12475   if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12476     E = BO->getRHS();
12477   } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12478     E = BO->getLHS();
12479   } else {
12480     ErrorInfo.Error = ErrorTy::InvalidComparison;
12481     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12482     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12483     return false;
12484   }
12485 
12486   if (S2->getElse()) {
12487     IsFailOnly = true;
12488 
12489     auto *Else = S2->getElse();
12490     if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12491       if (ElseCS->body_empty()) {
12492         ErrorInfo.Error = ErrorTy::NoStmt;
12493         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12494         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12495         return false;
12496       }
12497       if (ElseCS->size() > 1) {
12498         ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12499         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12500         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12501         return false;
12502       }
12503       Else = ElseCS->body_front();
12504     }
12505 
12506     auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12507     if (!ElseBO) {
12508       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12509       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12510       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12511       return false;
12512     }
12513     if (ElseBO->getOpcode() != BO_Assign) {
12514       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12515       ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12516       ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12517       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12518       return false;
12519     }
12520     if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12521       ErrorInfo.Error = ErrorTy::InvalidAssignment;
12522       ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12523       ErrorInfo.NoteLoc = X->getExprLoc();
12524       ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12525       ErrorInfo.NoteRange = X->getSourceRange();
12526       return false;
12527     }
12528 
12529     V = ElseBO->getLHS();
12530   }
12531 
12532   return checkType(ErrorInfo);
12533 }
12534 
checkStmt(Stmt * S,ErrorInfoTy & ErrorInfo)12535 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12536                                                   ErrorInfoTy &ErrorInfo) {
12537   // if(x == e) { x = d; } else { v = x; }
12538   if (auto *IS = dyn_cast<IfStmt>(S))
12539     return checkForm3(IS, ErrorInfo);
12540 
12541   auto *CS = dyn_cast<CompoundStmt>(S);
12542   if (!CS) {
12543     ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12544     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12545     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12546     return false;
12547   }
12548   if (CS->body_empty()) {
12549     ErrorInfo.Error = ErrorTy::NoStmt;
12550     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12551     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12552     return false;
12553   }
12554 
12555   // { if(x == e) { x = d; } else { v = x; } }
12556   if (CS->size() == 1) {
12557     auto *IS = dyn_cast<IfStmt>(CS->body_front());
12558     if (!IS) {
12559       ErrorInfo.Error = ErrorTy::NotIfStmt;
12560       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12561       ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12562           CS->body_front()->getSourceRange();
12563       return false;
12564     }
12565 
12566     return checkForm3(IS, ErrorInfo);
12567   } else if (CS->size() == 2) {
12568     auto *S1 = CS->body_front();
12569     auto *S2 = CS->body_back();
12570 
12571     Stmt *UpdateStmt = nullptr;
12572     Stmt *CondUpdateStmt = nullptr;
12573     Stmt *CondExprStmt = nullptr;
12574 
12575     if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12576       // It could be one of the following cases:
12577       // { v = x; cond-update-stmt }
12578       // { v = x; cond-expr-stmt }
12579       // { cond-expr-stmt; v = x; }
12580       // form 45
12581       if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12582           isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12583         // check if form 45
12584         if (isa<IfStmt>(S2))
12585           return checkForm45(CS, ErrorInfo);
12586         // { cond-expr-stmt; v = x; }
12587         CondExprStmt = S1;
12588         UpdateStmt = S2;
12589       } else {
12590         IsPostfixUpdate = true;
12591         UpdateStmt = S1;
12592         if (isa<IfStmt>(S2)) {
12593           // { v = x; cond-update-stmt }
12594           CondUpdateStmt = S2;
12595         } else {
12596           // { v = x; cond-expr-stmt }
12597           CondExprStmt = S2;
12598         }
12599       }
12600     } else {
12601       // { cond-update-stmt v = x; }
12602       UpdateStmt = S2;
12603       CondUpdateStmt = S1;
12604     }
12605 
12606     auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12607       auto *IS = dyn_cast<IfStmt>(CUS);
12608       if (!IS) {
12609         ErrorInfo.Error = ErrorTy::NotIfStmt;
12610         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12611         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12612         return false;
12613       }
12614 
12615       return checkCondUpdateStmt(IS, ErrorInfo);
12616     };
12617 
12618     // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12619     auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12620       auto *BO = dyn_cast<BinaryOperator>(US);
12621       if (!BO) {
12622         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12623         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12624         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12625         return false;
12626       }
12627       if (BO->getOpcode() != BO_Assign) {
12628         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12629         ErrorInfo.ErrorLoc = BO->getExprLoc();
12630         ErrorInfo.NoteLoc = BO->getOperatorLoc();
12631         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12632         return false;
12633       }
12634       if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12635         ErrorInfo.Error = ErrorTy::InvalidAssignment;
12636         ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12637         ErrorInfo.NoteLoc = this->X->getExprLoc();
12638         ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12639         ErrorInfo.NoteRange = this->X->getSourceRange();
12640         return false;
12641       }
12642 
12643       this->V = BO->getLHS();
12644 
12645       return true;
12646     };
12647 
12648     if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12649       return false;
12650     if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12651       return false;
12652     if (!CheckUpdateStmt(UpdateStmt))
12653       return false;
12654   } else {
12655     ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12656     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12657     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12658     return false;
12659   }
12660 
12661   return checkType(ErrorInfo);
12662 }
12663 } // namespace
12664 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12665 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12666                                             Stmt *AStmt,
12667                                             SourceLocation StartLoc,
12668                                             SourceLocation EndLoc) {
12669   // Register location of the first atomic directive.
12670   DSAStack->addAtomicDirectiveLoc(StartLoc);
12671   if (!AStmt)
12672     return StmtError();
12673 
12674   // 1.2.2 OpenMP Language Terminology
12675   // Structured block - An executable statement with a single entry at the
12676   // top and a single exit at the bottom.
12677   // The point of exit cannot be a branch out of the structured block.
12678   // longjmp() and throw() must not violate the entry/exit criteria.
12679   OpenMPClauseKind AtomicKind = OMPC_unknown;
12680   SourceLocation AtomicKindLoc;
12681   OpenMPClauseKind MemOrderKind = OMPC_unknown;
12682   SourceLocation MemOrderLoc;
12683   bool MutexClauseEncountered = false;
12684   llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12685   for (const OMPClause *C : Clauses) {
12686     switch (C->getClauseKind()) {
12687     case OMPC_read:
12688     case OMPC_write:
12689     case OMPC_update:
12690       MutexClauseEncountered = true;
12691       [[fallthrough]];
12692     case OMPC_capture:
12693     case OMPC_compare: {
12694       if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12695         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12696             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12697         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12698             << getOpenMPClauseName(AtomicKind);
12699       } else {
12700         AtomicKind = C->getClauseKind();
12701         AtomicKindLoc = C->getBeginLoc();
12702         if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12703           Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12704               << SourceRange(C->getBeginLoc(), C->getEndLoc());
12705           Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12706               << getOpenMPClauseName(AtomicKind);
12707         }
12708       }
12709       break;
12710     }
12711     case OMPC_fail: {
12712       if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
12713         Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
12714             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12715         return StmtError();
12716       }
12717       break;
12718     }
12719     case OMPC_seq_cst:
12720     case OMPC_acq_rel:
12721     case OMPC_acquire:
12722     case OMPC_release:
12723     case OMPC_relaxed: {
12724       if (MemOrderKind != OMPC_unknown) {
12725         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12726             << getOpenMPDirectiveName(OMPD_atomic) << 0
12727             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12728         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12729             << getOpenMPClauseName(MemOrderKind);
12730       } else {
12731         MemOrderKind = C->getClauseKind();
12732         MemOrderLoc = C->getBeginLoc();
12733       }
12734       break;
12735     }
12736     // The following clauses are allowed, but we don't need to do anything here.
12737     case OMPC_hint:
12738       break;
12739     default:
12740       llvm_unreachable("unknown clause is encountered");
12741     }
12742   }
12743   bool IsCompareCapture = false;
12744   if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12745       EncounteredAtomicKinds.contains(OMPC_capture)) {
12746     IsCompareCapture = true;
12747     AtomicKind = OMPC_compare;
12748   }
12749   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12750   // If atomic-clause is read then memory-order-clause must not be acq_rel or
12751   // release.
12752   // If atomic-clause is write then memory-order-clause must not be acq_rel or
12753   // acquire.
12754   // If atomic-clause is update or not present then memory-order-clause must not
12755   // be acq_rel or acquire.
12756   if ((AtomicKind == OMPC_read &&
12757        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12758       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12759         AtomicKind == OMPC_unknown) &&
12760        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12761     SourceLocation Loc = AtomicKindLoc;
12762     if (AtomicKind == OMPC_unknown)
12763       Loc = StartLoc;
12764     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12765         << getOpenMPClauseName(AtomicKind)
12766         << (AtomicKind == OMPC_unknown ? 1 : 0)
12767         << getOpenMPClauseName(MemOrderKind);
12768     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12769         << getOpenMPClauseName(MemOrderKind);
12770   }
12771 
12772   Stmt *Body = AStmt;
12773   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12774     Body = EWC->getSubExpr();
12775 
12776   Expr *X = nullptr;
12777   Expr *V = nullptr;
12778   Expr *E = nullptr;
12779   Expr *UE = nullptr;
12780   Expr *D = nullptr;
12781   Expr *CE = nullptr;
12782   Expr *R = nullptr;
12783   bool IsXLHSInRHSPart = false;
12784   bool IsPostfixUpdate = false;
12785   bool IsFailOnly = false;
12786   // OpenMP [2.12.6, atomic Construct]
12787   // In the next expressions:
12788   // * x and v (as applicable) are both l-value expressions with scalar type.
12789   // * During the execution of an atomic region, multiple syntactic
12790   // occurrences of x must designate the same storage location.
12791   // * Neither of v and expr (as applicable) may access the storage location
12792   // designated by x.
12793   // * Neither of x and expr (as applicable) may access the storage location
12794   // designated by v.
12795   // * expr is an expression with scalar type.
12796   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12797   // * binop, binop=, ++, and -- are not overloaded operators.
12798   // * The expression x binop expr must be numerically equivalent to x binop
12799   // (expr). This requirement is satisfied if the operators in expr have
12800   // precedence greater than binop, or by using parentheses around expr or
12801   // subexpressions of expr.
12802   // * The expression expr binop x must be numerically equivalent to (expr)
12803   // binop x. This requirement is satisfied if the operators in expr have
12804   // precedence equal to or greater than binop, or by using parentheses around
12805   // expr or subexpressions of expr.
12806   // * For forms that allow multiple occurrences of x, the number of times
12807   // that x is evaluated is unspecified.
12808   if (AtomicKind == OMPC_read) {
12809     enum {
12810       NotAnExpression,
12811       NotAnAssignmentOp,
12812       NotAScalarType,
12813       NotAnLValue,
12814       NoError
12815     } ErrorFound = NoError;
12816     SourceLocation ErrorLoc, NoteLoc;
12817     SourceRange ErrorRange, NoteRange;
12818     // If clause is read:
12819     //  v = x;
12820     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12821       const auto *AtomicBinOp =
12822           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12823       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12824         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12825         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12826         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12827             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12828           if (!X->isLValue() || !V->isLValue()) {
12829             const Expr *NotLValueExpr = X->isLValue() ? V : X;
12830             ErrorFound = NotAnLValue;
12831             ErrorLoc = AtomicBinOp->getExprLoc();
12832             ErrorRange = AtomicBinOp->getSourceRange();
12833             NoteLoc = NotLValueExpr->getExprLoc();
12834             NoteRange = NotLValueExpr->getSourceRange();
12835           }
12836         } else if (!X->isInstantiationDependent() ||
12837                    !V->isInstantiationDependent()) {
12838           const Expr *NotScalarExpr =
12839               (X->isInstantiationDependent() || X->getType()->isScalarType())
12840                   ? V
12841                   : X;
12842           ErrorFound = NotAScalarType;
12843           ErrorLoc = AtomicBinOp->getExprLoc();
12844           ErrorRange = AtomicBinOp->getSourceRange();
12845           NoteLoc = NotScalarExpr->getExprLoc();
12846           NoteRange = NotScalarExpr->getSourceRange();
12847         }
12848       } else if (!AtomicBody->isInstantiationDependent()) {
12849         ErrorFound = NotAnAssignmentOp;
12850         ErrorLoc = AtomicBody->getExprLoc();
12851         ErrorRange = AtomicBody->getSourceRange();
12852         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12853                               : AtomicBody->getExprLoc();
12854         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12855                                 : AtomicBody->getSourceRange();
12856       }
12857     } else {
12858       ErrorFound = NotAnExpression;
12859       NoteLoc = ErrorLoc = Body->getBeginLoc();
12860       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12861     }
12862     if (ErrorFound != NoError) {
12863       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12864           << ErrorRange;
12865       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12866           << ErrorFound << NoteRange;
12867       return StmtError();
12868     }
12869     if (CurContext->isDependentContext())
12870       V = X = nullptr;
12871   } else if (AtomicKind == OMPC_write) {
12872     enum {
12873       NotAnExpression,
12874       NotAnAssignmentOp,
12875       NotAScalarType,
12876       NotAnLValue,
12877       NoError
12878     } ErrorFound = NoError;
12879     SourceLocation ErrorLoc, NoteLoc;
12880     SourceRange ErrorRange, NoteRange;
12881     // If clause is write:
12882     //  x = expr;
12883     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12884       const auto *AtomicBinOp =
12885           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12886       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12887         X = AtomicBinOp->getLHS();
12888         E = AtomicBinOp->getRHS();
12889         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12890             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12891           if (!X->isLValue()) {
12892             ErrorFound = NotAnLValue;
12893             ErrorLoc = AtomicBinOp->getExprLoc();
12894             ErrorRange = AtomicBinOp->getSourceRange();
12895             NoteLoc = X->getExprLoc();
12896             NoteRange = X->getSourceRange();
12897           }
12898         } else if (!X->isInstantiationDependent() ||
12899                    !E->isInstantiationDependent()) {
12900           const Expr *NotScalarExpr =
12901               (X->isInstantiationDependent() || X->getType()->isScalarType())
12902                   ? E
12903                   : X;
12904           ErrorFound = NotAScalarType;
12905           ErrorLoc = AtomicBinOp->getExprLoc();
12906           ErrorRange = AtomicBinOp->getSourceRange();
12907           NoteLoc = NotScalarExpr->getExprLoc();
12908           NoteRange = NotScalarExpr->getSourceRange();
12909         }
12910       } else if (!AtomicBody->isInstantiationDependent()) {
12911         ErrorFound = NotAnAssignmentOp;
12912         ErrorLoc = AtomicBody->getExprLoc();
12913         ErrorRange = AtomicBody->getSourceRange();
12914         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12915                               : AtomicBody->getExprLoc();
12916         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12917                                 : AtomicBody->getSourceRange();
12918       }
12919     } else {
12920       ErrorFound = NotAnExpression;
12921       NoteLoc = ErrorLoc = Body->getBeginLoc();
12922       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12923     }
12924     if (ErrorFound != NoError) {
12925       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12926           << ErrorRange;
12927       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12928           << ErrorFound << NoteRange;
12929       return StmtError();
12930     }
12931     if (CurContext->isDependentContext())
12932       E = X = nullptr;
12933   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12934     // If clause is update:
12935     //  x++;
12936     //  x--;
12937     //  ++x;
12938     //  --x;
12939     //  x binop= expr;
12940     //  x = x binop expr;
12941     //  x = expr binop x;
12942     OpenMPAtomicUpdateChecker Checker(*this);
12943     if (Checker.checkStatement(
12944             Body,
12945             (AtomicKind == OMPC_update)
12946                 ? diag::err_omp_atomic_update_not_expression_statement
12947                 : diag::err_omp_atomic_not_expression_statement,
12948             diag::note_omp_atomic_update))
12949       return StmtError();
12950     if (!CurContext->isDependentContext()) {
12951       E = Checker.getExpr();
12952       X = Checker.getX();
12953       UE = Checker.getUpdateExpr();
12954       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12955     }
12956   } else if (AtomicKind == OMPC_capture) {
12957     enum {
12958       NotAnAssignmentOp,
12959       NotACompoundStatement,
12960       NotTwoSubstatements,
12961       NotASpecificExpression,
12962       NoError
12963     } ErrorFound = NoError;
12964     SourceLocation ErrorLoc, NoteLoc;
12965     SourceRange ErrorRange, NoteRange;
12966     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12967       // If clause is a capture:
12968       //  v = x++;
12969       //  v = x--;
12970       //  v = ++x;
12971       //  v = --x;
12972       //  v = x binop= expr;
12973       //  v = x = x binop expr;
12974       //  v = x = expr binop x;
12975       const auto *AtomicBinOp =
12976           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12977       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12978         V = AtomicBinOp->getLHS();
12979         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12980         OpenMPAtomicUpdateChecker Checker(*this);
12981         if (Checker.checkStatement(
12982                 Body, diag::err_omp_atomic_capture_not_expression_statement,
12983                 diag::note_omp_atomic_update))
12984           return StmtError();
12985         E = Checker.getExpr();
12986         X = Checker.getX();
12987         UE = Checker.getUpdateExpr();
12988         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12989         IsPostfixUpdate = Checker.isPostfixUpdate();
12990       } else if (!AtomicBody->isInstantiationDependent()) {
12991         ErrorLoc = AtomicBody->getExprLoc();
12992         ErrorRange = AtomicBody->getSourceRange();
12993         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12994                               : AtomicBody->getExprLoc();
12995         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12996                                 : AtomicBody->getSourceRange();
12997         ErrorFound = NotAnAssignmentOp;
12998       }
12999       if (ErrorFound != NoError) {
13000         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
13001             << ErrorRange;
13002         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13003         return StmtError();
13004       }
13005       if (CurContext->isDependentContext())
13006         UE = V = E = X = nullptr;
13007     } else {
13008       // If clause is a capture:
13009       //  { v = x; x = expr; }
13010       //  { v = x; x++; }
13011       //  { v = x; x--; }
13012       //  { v = x; ++x; }
13013       //  { v = x; --x; }
13014       //  { v = x; x binop= expr; }
13015       //  { v = x; x = x binop expr; }
13016       //  { v = x; x = expr binop x; }
13017       //  { x++; v = x; }
13018       //  { x--; v = x; }
13019       //  { ++x; v = x; }
13020       //  { --x; v = x; }
13021       //  { x binop= expr; v = x; }
13022       //  { x = x binop expr; v = x; }
13023       //  { x = expr binop x; v = x; }
13024       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
13025         // Check that this is { expr1; expr2; }
13026         if (CS->size() == 2) {
13027           Stmt *First = CS->body_front();
13028           Stmt *Second = CS->body_back();
13029           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
13030             First = EWC->getSubExpr()->IgnoreParenImpCasts();
13031           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
13032             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
13033           // Need to find what subexpression is 'v' and what is 'x'.
13034           OpenMPAtomicUpdateChecker Checker(*this);
13035           bool IsUpdateExprFound = !Checker.checkStatement(Second);
13036           BinaryOperator *BinOp = nullptr;
13037           if (IsUpdateExprFound) {
13038             BinOp = dyn_cast<BinaryOperator>(First);
13039             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13040           }
13041           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
13042             //  { v = x; x++; }
13043             //  { v = x; x--; }
13044             //  { v = x; ++x; }
13045             //  { v = x; --x; }
13046             //  { v = x; x binop= expr; }
13047             //  { v = x; x = x binop expr; }
13048             //  { v = x; x = expr binop x; }
13049             // Check that the first expression has form v = x.
13050             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13051             llvm::FoldingSetNodeID XId, PossibleXId;
13052             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13053             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13054             IsUpdateExprFound = XId == PossibleXId;
13055             if (IsUpdateExprFound) {
13056               V = BinOp->getLHS();
13057               X = Checker.getX();
13058               E = Checker.getExpr();
13059               UE = Checker.getUpdateExpr();
13060               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13061               IsPostfixUpdate = true;
13062             }
13063           }
13064           if (!IsUpdateExprFound) {
13065             IsUpdateExprFound = !Checker.checkStatement(First);
13066             BinOp = nullptr;
13067             if (IsUpdateExprFound) {
13068               BinOp = dyn_cast<BinaryOperator>(Second);
13069               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13070             }
13071             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
13072               //  { x++; v = x; }
13073               //  { x--; v = x; }
13074               //  { ++x; v = x; }
13075               //  { --x; v = x; }
13076               //  { x binop= expr; v = x; }
13077               //  { x = x binop expr; v = x; }
13078               //  { x = expr binop x; v = x; }
13079               // Check that the second expression has form v = x.
13080               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13081               llvm::FoldingSetNodeID XId, PossibleXId;
13082               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13083               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13084               IsUpdateExprFound = XId == PossibleXId;
13085               if (IsUpdateExprFound) {
13086                 V = BinOp->getLHS();
13087                 X = Checker.getX();
13088                 E = Checker.getExpr();
13089                 UE = Checker.getUpdateExpr();
13090                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13091                 IsPostfixUpdate = false;
13092               }
13093             }
13094           }
13095           if (!IsUpdateExprFound) {
13096             //  { v = x; x = expr; }
13097             auto *FirstExpr = dyn_cast<Expr>(First);
13098             auto *SecondExpr = dyn_cast<Expr>(Second);
13099             if (!FirstExpr || !SecondExpr ||
13100                 !(FirstExpr->isInstantiationDependent() ||
13101                   SecondExpr->isInstantiationDependent())) {
13102               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
13103               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13104                 ErrorFound = NotAnAssignmentOp;
13105                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13106                                                 : First->getBeginLoc();
13107                 NoteRange = ErrorRange = FirstBinOp
13108                                              ? FirstBinOp->getSourceRange()
13109                                              : SourceRange(ErrorLoc, ErrorLoc);
13110               } else {
13111                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13112                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13113                   ErrorFound = NotAnAssignmentOp;
13114                   NoteLoc = ErrorLoc = SecondBinOp
13115                                            ? SecondBinOp->getOperatorLoc()
13116                                            : Second->getBeginLoc();
13117                   NoteRange = ErrorRange =
13118                       SecondBinOp ? SecondBinOp->getSourceRange()
13119                                   : SourceRange(ErrorLoc, ErrorLoc);
13120                 } else {
13121                   Expr *PossibleXRHSInFirst =
13122                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
13123                   Expr *PossibleXLHSInSecond =
13124                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
13125                   llvm::FoldingSetNodeID X1Id, X2Id;
13126                   PossibleXRHSInFirst->Profile(X1Id, Context,
13127                                                /*Canonical=*/true);
13128                   PossibleXLHSInSecond->Profile(X2Id, Context,
13129                                                 /*Canonical=*/true);
13130                   IsUpdateExprFound = X1Id == X2Id;
13131                   if (IsUpdateExprFound) {
13132                     V = FirstBinOp->getLHS();
13133                     X = SecondBinOp->getLHS();
13134                     E = SecondBinOp->getRHS();
13135                     UE = nullptr;
13136                     IsXLHSInRHSPart = false;
13137                     IsPostfixUpdate = true;
13138                   } else {
13139                     ErrorFound = NotASpecificExpression;
13140                     ErrorLoc = FirstBinOp->getExprLoc();
13141                     ErrorRange = FirstBinOp->getSourceRange();
13142                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13143                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
13144                   }
13145                 }
13146               }
13147             }
13148           }
13149         } else {
13150           NoteLoc = ErrorLoc = Body->getBeginLoc();
13151           NoteRange = ErrorRange =
13152               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13153           ErrorFound = NotTwoSubstatements;
13154         }
13155       } else {
13156         NoteLoc = ErrorLoc = Body->getBeginLoc();
13157         NoteRange = ErrorRange =
13158             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13159         ErrorFound = NotACompoundStatement;
13160       }
13161     }
13162     if (ErrorFound != NoError) {
13163       Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13164           << ErrorRange;
13165       Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13166       return StmtError();
13167     }
13168     if (CurContext->isDependentContext())
13169       UE = V = E = X = nullptr;
13170   } else if (AtomicKind == OMPC_compare) {
13171     if (IsCompareCapture) {
13172       OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13173       OpenMPAtomicCompareCaptureChecker Checker(*this);
13174       if (!Checker.checkStmt(Body, ErrorInfo)) {
13175         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13176             << ErrorInfo.ErrorRange;
13177         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13178             << ErrorInfo.Error << ErrorInfo.NoteRange;
13179         return StmtError();
13180       }
13181       X = Checker.getX();
13182       E = Checker.getE();
13183       D = Checker.getD();
13184       CE = Checker.getCond();
13185       V = Checker.getV();
13186       R = Checker.getR();
13187       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13188       IsXLHSInRHSPart = Checker.isXBinopExpr();
13189       IsFailOnly = Checker.isFailOnly();
13190       IsPostfixUpdate = Checker.isPostfixUpdate();
13191     } else {
13192       OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13193       OpenMPAtomicCompareChecker Checker(*this);
13194       if (!Checker.checkStmt(Body, ErrorInfo)) {
13195         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13196             << ErrorInfo.ErrorRange;
13197         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13198           << ErrorInfo.Error << ErrorInfo.NoteRange;
13199         return StmtError();
13200       }
13201       X = Checker.getX();
13202       E = Checker.getE();
13203       D = Checker.getD();
13204       CE = Checker.getCond();
13205       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13206       IsXLHSInRHSPart = Checker.isXBinopExpr();
13207     }
13208   }
13209 
13210   setFunctionHasBranchProtectedScope();
13211 
13212   return OMPAtomicDirective::Create(
13213       Context, StartLoc, EndLoc, Clauses, AStmt,
13214       {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13215 }
13216 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)13217 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
13218                                             Stmt *AStmt,
13219                                             SourceLocation StartLoc,
13220                                             SourceLocation EndLoc) {
13221   if (!AStmt)
13222     return StmtError();
13223 
13224   auto *CS = cast<CapturedStmt>(AStmt);
13225   // 1.2.2 OpenMP Language Terminology
13226   // Structured block - An executable statement with a single entry at the
13227   // top and a single exit at the bottom.
13228   // The point of exit cannot be a branch out of the structured block.
13229   // longjmp() and throw() must not violate the entry/exit criteria.
13230   CS->getCapturedDecl()->setNothrow();
13231   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
13232        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13233     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13234     // 1.2.2 OpenMP Language Terminology
13235     // Structured block - An executable statement with a single entry at the
13236     // top and a single exit at the bottom.
13237     // The point of exit cannot be a branch out of the structured block.
13238     // longjmp() and throw() must not violate the entry/exit criteria.
13239     CS->getCapturedDecl()->setNothrow();
13240   }
13241 
13242   // OpenMP [2.16, Nesting of Regions]
13243   // If specified, a teams construct must be contained within a target
13244   // construct. That target construct must contain no statements or directives
13245   // outside of the teams construct.
13246   if (DSAStack->hasInnerTeamsRegion()) {
13247     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
13248     bool OMPTeamsFound = true;
13249     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
13250       auto I = CS->body_begin();
13251       while (I != CS->body_end()) {
13252         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13253         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
13254             OMPTeamsFound) {
13255 
13256           OMPTeamsFound = false;
13257           break;
13258         }
13259         ++I;
13260       }
13261       assert(I != CS->body_end() && "Not found statement");
13262       S = *I;
13263     } else {
13264       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13265       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
13266     }
13267     if (!OMPTeamsFound) {
13268       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13269       Diag(DSAStack->getInnerTeamsRegionLoc(),
13270            diag::note_omp_nested_teams_construct_here);
13271       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13272           << isa<OMPExecutableDirective>(S);
13273       return StmtError();
13274     }
13275   }
13276 
13277   setFunctionHasBranchProtectedScope();
13278 
13279   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13280 }
13281 
13282 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)13283 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
13284                                          Stmt *AStmt, SourceLocation StartLoc,
13285                                          SourceLocation EndLoc) {
13286   if (!AStmt)
13287     return StmtError();
13288 
13289   auto *CS = cast<CapturedStmt>(AStmt);
13290   // 1.2.2 OpenMP Language Terminology
13291   // Structured block - An executable statement with a single entry at the
13292   // top and a single exit at the bottom.
13293   // The point of exit cannot be a branch out of the structured block.
13294   // longjmp() and throw() must not violate the entry/exit criteria.
13295   CS->getCapturedDecl()->setNothrow();
13296   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
13297        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13298     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13299     // 1.2.2 OpenMP Language Terminology
13300     // Structured block - An executable statement with a single entry at the
13301     // top and a single exit at the bottom.
13302     // The point of exit cannot be a branch out of the structured block.
13303     // longjmp() and throw() must not violate the entry/exit criteria.
13304     CS->getCapturedDecl()->setNothrow();
13305   }
13306 
13307   setFunctionHasBranchProtectedScope();
13308 
13309   return OMPTargetParallelDirective::Create(
13310       Context, StartLoc, EndLoc, Clauses, AStmt,
13311       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13312 }
13313 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13314 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
13315     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13316     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13317   if (!AStmt)
13318     return StmtError();
13319 
13320   auto *CS = cast<CapturedStmt>(AStmt);
13321   // 1.2.2 OpenMP Language Terminology
13322   // Structured block - An executable statement with a single entry at the
13323   // top and a single exit at the bottom.
13324   // The point of exit cannot be a branch out of the structured block.
13325   // longjmp() and throw() must not violate the entry/exit criteria.
13326   CS->getCapturedDecl()->setNothrow();
13327   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13328        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13329     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13330     // 1.2.2 OpenMP Language Terminology
13331     // Structured block - An executable statement with a single entry at the
13332     // top and a single exit at the bottom.
13333     // The point of exit cannot be a branch out of the structured block.
13334     // longjmp() and throw() must not violate the entry/exit criteria.
13335     CS->getCapturedDecl()->setNothrow();
13336   }
13337 
13338   OMPLoopBasedDirective::HelperExprs B;
13339   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13340   // define the nested loops number.
13341   unsigned NestedLoopCount =
13342       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13343                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13344                       VarsWithImplicitDSA, B);
13345   if (NestedLoopCount == 0)
13346     return StmtError();
13347 
13348   assert((CurContext->isDependentContext() || B.builtAll()) &&
13349          "omp target parallel for loop exprs were not built");
13350 
13351   if (!CurContext->isDependentContext()) {
13352     // Finalize the clauses that need pre-built expressions for CodeGen.
13353     for (OMPClause *C : Clauses) {
13354       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13355         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13356                                      B.NumIterations, *this, CurScope,
13357                                      DSAStack))
13358           return StmtError();
13359     }
13360   }
13361 
13362   setFunctionHasBranchProtectedScope();
13363   return OMPTargetParallelForDirective::Create(
13364       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13365       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13366 }
13367 
13368 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)13369 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13370                        const OpenMPClauseKind K) {
13371   return llvm::any_of(
13372       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13373 }
13374 
13375 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)13376 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13377                        const Params... ClauseTypes) {
13378   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13379 }
13380 
13381 /// Check if the variables in the mapping clause are externally visible.
isClauseMappable(ArrayRef<OMPClause * > Clauses)13382 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13383   for (const OMPClause *C : Clauses) {
13384     if (auto *TC = dyn_cast<OMPToClause>(C))
13385       return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13386         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13387                (VD->isExternallyVisible() &&
13388                 VD->getVisibility() != HiddenVisibility);
13389       });
13390     else if (auto *FC = dyn_cast<OMPFromClause>(C))
13391       return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13392         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13393                (VD->isExternallyVisible() &&
13394                 VD->getVisibility() != HiddenVisibility);
13395       });
13396   }
13397 
13398   return true;
13399 }
13400 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)13401 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13402                                                 Stmt *AStmt,
13403                                                 SourceLocation StartLoc,
13404                                                 SourceLocation EndLoc) {
13405   if (!AStmt)
13406     return StmtError();
13407 
13408   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13409 
13410   // OpenMP [2.12.2, target data Construct, Restrictions]
13411   // At least one map, use_device_addr or use_device_ptr clause must appear on
13412   // the directive.
13413   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13414       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
13415     StringRef Expected;
13416     if (LangOpts.OpenMP < 50)
13417       Expected = "'map' or 'use_device_ptr'";
13418     else
13419       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13420     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13421         << Expected << getOpenMPDirectiveName(OMPD_target_data);
13422     return StmtError();
13423   }
13424 
13425   setFunctionHasBranchProtectedScope();
13426 
13427   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13428                                         AStmt);
13429 }
13430 
13431 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)13432 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13433                                           SourceLocation StartLoc,
13434                                           SourceLocation EndLoc, Stmt *AStmt) {
13435   if (!AStmt)
13436     return StmtError();
13437 
13438   auto *CS = cast<CapturedStmt>(AStmt);
13439   // 1.2.2 OpenMP Language Terminology
13440   // Structured block - An executable statement with a single entry at the
13441   // top and a single exit at the bottom.
13442   // The point of exit cannot be a branch out of the structured block.
13443   // longjmp() and throw() must not violate the entry/exit criteria.
13444   CS->getCapturedDecl()->setNothrow();
13445   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13446        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13447     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13448     // 1.2.2 OpenMP Language Terminology
13449     // Structured block - An executable statement with a single entry at the
13450     // top and a single exit at the bottom.
13451     // The point of exit cannot be a branch out of the structured block.
13452     // longjmp() and throw() must not violate the entry/exit criteria.
13453     CS->getCapturedDecl()->setNothrow();
13454   }
13455 
13456   // OpenMP [2.10.2, Restrictions, p. 99]
13457   // At least one map clause must appear on the directive.
13458   if (!hasClauses(Clauses, OMPC_map)) {
13459     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13460         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13461     return StmtError();
13462   }
13463 
13464   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13465                                              AStmt);
13466 }
13467 
13468 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)13469 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13470                                          SourceLocation StartLoc,
13471                                          SourceLocation EndLoc, Stmt *AStmt) {
13472   if (!AStmt)
13473     return StmtError();
13474 
13475   auto *CS = cast<CapturedStmt>(AStmt);
13476   // 1.2.2 OpenMP Language Terminology
13477   // Structured block - An executable statement with a single entry at the
13478   // top and a single exit at the bottom.
13479   // The point of exit cannot be a branch out of the structured block.
13480   // longjmp() and throw() must not violate the entry/exit criteria.
13481   CS->getCapturedDecl()->setNothrow();
13482   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13483        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13484     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13485     // 1.2.2 OpenMP Language Terminology
13486     // Structured block - An executable statement with a single entry at the
13487     // top and a single exit at the bottom.
13488     // The point of exit cannot be a branch out of the structured block.
13489     // longjmp() and throw() must not violate the entry/exit criteria.
13490     CS->getCapturedDecl()->setNothrow();
13491   }
13492 
13493   // OpenMP [2.10.3, Restrictions, p. 102]
13494   // At least one map clause must appear on the directive.
13495   if (!hasClauses(Clauses, OMPC_map)) {
13496     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13497         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13498     return StmtError();
13499   }
13500 
13501   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13502                                             AStmt);
13503 }
13504 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)13505 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13506                                                   SourceLocation StartLoc,
13507                                                   SourceLocation EndLoc,
13508                                                   Stmt *AStmt) {
13509   if (!AStmt)
13510     return StmtError();
13511 
13512   auto *CS = cast<CapturedStmt>(AStmt);
13513   // 1.2.2 OpenMP Language Terminology
13514   // Structured block - An executable statement with a single entry at the
13515   // top and a single exit at the bottom.
13516   // The point of exit cannot be a branch out of the structured block.
13517   // longjmp() and throw() must not violate the entry/exit criteria.
13518   CS->getCapturedDecl()->setNothrow();
13519   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13520        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13521     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13522     // 1.2.2 OpenMP Language Terminology
13523     // Structured block - An executable statement with a single entry at the
13524     // top and a single exit at the bottom.
13525     // The point of exit cannot be a branch out of the structured block.
13526     // longjmp() and throw() must not violate the entry/exit criteria.
13527     CS->getCapturedDecl()->setNothrow();
13528   }
13529 
13530   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13531     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13532     return StmtError();
13533   }
13534 
13535   if (!isClauseMappable(Clauses)) {
13536     Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13537     return StmtError();
13538   }
13539 
13540   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13541                                           AStmt);
13542 }
13543 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)13544 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13545                                            Stmt *AStmt, SourceLocation StartLoc,
13546                                            SourceLocation EndLoc) {
13547   if (!AStmt)
13548     return StmtError();
13549 
13550   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
13551   if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target))
13552     Diag(StartLoc, diag::warn_hip_omp_target_directives);
13553 
13554   auto *CS = cast<CapturedStmt>(AStmt);
13555   // 1.2.2 OpenMP Language Terminology
13556   // Structured block - An executable statement with a single entry at the
13557   // top and a single exit at the bottom.
13558   // The point of exit cannot be a branch out of the structured block.
13559   // longjmp() and throw() must not violate the entry/exit criteria.
13560   CS->getCapturedDecl()->setNothrow();
13561 
13562   setFunctionHasBranchProtectedScope();
13563 
13564   DSAStack->setParentTeamsRegionLoc(StartLoc);
13565 
13566   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13567 }
13568 
13569 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)13570 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13571                                             SourceLocation EndLoc,
13572                                             OpenMPDirectiveKind CancelRegion) {
13573   if (DSAStack->isParentNowaitRegion()) {
13574     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13575     return StmtError();
13576   }
13577   if (DSAStack->isParentOrderedRegion()) {
13578     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13579     return StmtError();
13580   }
13581   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13582                                                CancelRegion);
13583 }
13584 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)13585 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13586                                             SourceLocation StartLoc,
13587                                             SourceLocation EndLoc,
13588                                             OpenMPDirectiveKind CancelRegion) {
13589   if (DSAStack->isParentNowaitRegion()) {
13590     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13591     return StmtError();
13592   }
13593   if (DSAStack->isParentOrderedRegion()) {
13594     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13595     return StmtError();
13596   }
13597   DSAStack->setParentCancelRegion(/*Cancel=*/true);
13598   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13599                                     CancelRegion);
13600 }
13601 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)13602 static bool checkReductionClauseWithNogroup(Sema &S,
13603                                             ArrayRef<OMPClause *> Clauses) {
13604   const OMPClause *ReductionClause = nullptr;
13605   const OMPClause *NogroupClause = nullptr;
13606   for (const OMPClause *C : Clauses) {
13607     if (C->getClauseKind() == OMPC_reduction) {
13608       ReductionClause = C;
13609       if (NogroupClause)
13610         break;
13611       continue;
13612     }
13613     if (C->getClauseKind() == OMPC_nogroup) {
13614       NogroupClause = C;
13615       if (ReductionClause)
13616         break;
13617       continue;
13618     }
13619   }
13620   if (ReductionClause && NogroupClause) {
13621     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13622         << SourceRange(NogroupClause->getBeginLoc(),
13623                        NogroupClause->getEndLoc());
13624     return true;
13625   }
13626   return false;
13627 }
13628 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13629 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13630     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13631     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13632   if (!AStmt)
13633     return StmtError();
13634 
13635   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13636   OMPLoopBasedDirective::HelperExprs B;
13637   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13638   // define the nested loops number.
13639   unsigned NestedLoopCount =
13640       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13641                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13642                       VarsWithImplicitDSA, B);
13643   if (NestedLoopCount == 0)
13644     return StmtError();
13645 
13646   assert((CurContext->isDependentContext() || B.builtAll()) &&
13647          "omp for loop exprs were not built");
13648 
13649   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13650   // The grainsize clause and num_tasks clause are mutually exclusive and may
13651   // not appear on the same taskloop directive.
13652   if (checkMutuallyExclusiveClauses(*this, Clauses,
13653                                     {OMPC_grainsize, OMPC_num_tasks}))
13654     return StmtError();
13655   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13656   // If a reduction clause is present on the taskloop directive, the nogroup
13657   // clause must not be specified.
13658   if (checkReductionClauseWithNogroup(*this, Clauses))
13659     return StmtError();
13660 
13661   setFunctionHasBranchProtectedScope();
13662   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13663                                       NestedLoopCount, Clauses, AStmt, B,
13664                                       DSAStack->isCancelRegion());
13665 }
13666 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13667 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13668     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13669     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13670   if (!AStmt)
13671     return StmtError();
13672 
13673   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13674   OMPLoopBasedDirective::HelperExprs B;
13675   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13676   // define the nested loops number.
13677   unsigned NestedLoopCount =
13678       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13679                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13680                       VarsWithImplicitDSA, B);
13681   if (NestedLoopCount == 0)
13682     return StmtError();
13683 
13684   assert((CurContext->isDependentContext() || B.builtAll()) &&
13685          "omp for loop exprs were not built");
13686 
13687   if (!CurContext->isDependentContext()) {
13688     // Finalize the clauses that need pre-built expressions for CodeGen.
13689     for (OMPClause *C : Clauses) {
13690       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13691         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13692                                      B.NumIterations, *this, CurScope,
13693                                      DSAStack))
13694           return StmtError();
13695     }
13696   }
13697 
13698   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13699   // The grainsize clause and num_tasks clause are mutually exclusive and may
13700   // not appear on the same taskloop directive.
13701   if (checkMutuallyExclusiveClauses(*this, Clauses,
13702                                     {OMPC_grainsize, OMPC_num_tasks}))
13703     return StmtError();
13704   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13705   // If a reduction clause is present on the taskloop directive, the nogroup
13706   // clause must not be specified.
13707   if (checkReductionClauseWithNogroup(*this, Clauses))
13708     return StmtError();
13709   if (checkSimdlenSafelenSpecified(*this, Clauses))
13710     return StmtError();
13711 
13712   setFunctionHasBranchProtectedScope();
13713   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13714                                           NestedLoopCount, Clauses, AStmt, B);
13715 }
13716 
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13717 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13718     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13719     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13720   if (!AStmt)
13721     return StmtError();
13722 
13723   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13724   OMPLoopBasedDirective::HelperExprs B;
13725   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13726   // define the nested loops number.
13727   unsigned NestedLoopCount =
13728       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13729                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13730                       VarsWithImplicitDSA, B);
13731   if (NestedLoopCount == 0)
13732     return StmtError();
13733 
13734   assert((CurContext->isDependentContext() || B.builtAll()) &&
13735          "omp for loop exprs were not built");
13736 
13737   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13738   // The grainsize clause and num_tasks clause are mutually exclusive and may
13739   // not appear on the same taskloop directive.
13740   if (checkMutuallyExclusiveClauses(*this, Clauses,
13741                                     {OMPC_grainsize, OMPC_num_tasks}))
13742     return StmtError();
13743   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13744   // If a reduction clause is present on the taskloop directive, the nogroup
13745   // clause must not be specified.
13746   if (checkReductionClauseWithNogroup(*this, Clauses))
13747     return StmtError();
13748 
13749   setFunctionHasBranchProtectedScope();
13750   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13751                                             NestedLoopCount, Clauses, AStmt, B,
13752                                             DSAStack->isCancelRegion());
13753 }
13754 
ActOnOpenMPMaskedTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13755 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13756     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13757     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13758   if (!AStmt)
13759     return StmtError();
13760 
13761   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13762   OMPLoopBasedDirective::HelperExprs B;
13763   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13764   // define the nested loops number.
13765   unsigned NestedLoopCount =
13766       checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13767                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13768                       VarsWithImplicitDSA, B);
13769   if (NestedLoopCount == 0)
13770     return StmtError();
13771 
13772   assert((CurContext->isDependentContext() || B.builtAll()) &&
13773          "omp for loop exprs were not built");
13774 
13775   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13776   // The grainsize clause and num_tasks clause are mutually exclusive and may
13777   // not appear on the same taskloop directive.
13778   if (checkMutuallyExclusiveClauses(*this, Clauses,
13779                                     {OMPC_grainsize, OMPC_num_tasks}))
13780     return StmtError();
13781   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13782   // If a reduction clause is present on the taskloop directive, the nogroup
13783   // clause must not be specified.
13784   if (checkReductionClauseWithNogroup(*this, Clauses))
13785     return StmtError();
13786 
13787   setFunctionHasBranchProtectedScope();
13788   return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13789                                             NestedLoopCount, Clauses, AStmt, B,
13790                                             DSAStack->isCancelRegion());
13791 }
13792 
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13793 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13794     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13795     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13796   if (!AStmt)
13797     return StmtError();
13798 
13799   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13800   OMPLoopBasedDirective::HelperExprs B;
13801   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13802   // define the nested loops number.
13803   unsigned NestedLoopCount =
13804       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13805                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13806                       VarsWithImplicitDSA, B);
13807   if (NestedLoopCount == 0)
13808     return StmtError();
13809 
13810   assert((CurContext->isDependentContext() || B.builtAll()) &&
13811          "omp for loop exprs were not built");
13812 
13813   if (!CurContext->isDependentContext()) {
13814     // Finalize the clauses that need pre-built expressions for CodeGen.
13815     for (OMPClause *C : Clauses) {
13816       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13817         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13818                                      B.NumIterations, *this, CurScope,
13819                                      DSAStack))
13820           return StmtError();
13821     }
13822   }
13823 
13824   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13825   // The grainsize clause and num_tasks clause are mutually exclusive and may
13826   // not appear on the same taskloop directive.
13827   if (checkMutuallyExclusiveClauses(*this, Clauses,
13828                                     {OMPC_grainsize, OMPC_num_tasks}))
13829     return StmtError();
13830   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13831   // If a reduction clause is present on the taskloop directive, the nogroup
13832   // clause must not be specified.
13833   if (checkReductionClauseWithNogroup(*this, Clauses))
13834     return StmtError();
13835   if (checkSimdlenSafelenSpecified(*this, Clauses))
13836     return StmtError();
13837 
13838   setFunctionHasBranchProtectedScope();
13839   return OMPMasterTaskLoopSimdDirective::Create(
13840       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13841 }
13842 
ActOnOpenMPMaskedTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13843 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13844     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13845     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13846   if (!AStmt)
13847     return StmtError();
13848 
13849   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13850   OMPLoopBasedDirective::HelperExprs B;
13851   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13852   // define the nested loops number.
13853   unsigned NestedLoopCount =
13854       checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13855                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13856                       VarsWithImplicitDSA, B);
13857   if (NestedLoopCount == 0)
13858     return StmtError();
13859 
13860   assert((CurContext->isDependentContext() || B.builtAll()) &&
13861          "omp for loop exprs were not built");
13862 
13863   if (!CurContext->isDependentContext()) {
13864     // Finalize the clauses that need pre-built expressions for CodeGen.
13865     for (OMPClause *C : Clauses) {
13866       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13867         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13868                                      B.NumIterations, *this, CurScope,
13869                                      DSAStack))
13870           return StmtError();
13871     }
13872   }
13873 
13874   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13875   // The grainsize clause and num_tasks clause are mutually exclusive and may
13876   // not appear on the same taskloop directive.
13877   if (checkMutuallyExclusiveClauses(*this, Clauses,
13878                                     {OMPC_grainsize, OMPC_num_tasks}))
13879     return StmtError();
13880   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13881   // If a reduction clause is present on the taskloop directive, the nogroup
13882   // clause must not be specified.
13883   if (checkReductionClauseWithNogroup(*this, Clauses))
13884     return StmtError();
13885   if (checkSimdlenSafelenSpecified(*this, Clauses))
13886     return StmtError();
13887 
13888   setFunctionHasBranchProtectedScope();
13889   return OMPMaskedTaskLoopSimdDirective::Create(
13890       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13891 }
13892 
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13893 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13894     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13895     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13896   if (!AStmt)
13897     return StmtError();
13898 
13899   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13900   auto *CS = cast<CapturedStmt>(AStmt);
13901   // 1.2.2 OpenMP Language Terminology
13902   // Structured block - An executable statement with a single entry at the
13903   // top and a single exit at the bottom.
13904   // The point of exit cannot be a branch out of the structured block.
13905   // longjmp() and throw() must not violate the entry/exit criteria.
13906   CS->getCapturedDecl()->setNothrow();
13907   for (int ThisCaptureLevel =
13908            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13909        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13910     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13911     // 1.2.2 OpenMP Language Terminology
13912     // Structured block - An executable statement with a single entry at the
13913     // top and a single exit at the bottom.
13914     // The point of exit cannot be a branch out of the structured block.
13915     // longjmp() and throw() must not violate the entry/exit criteria.
13916     CS->getCapturedDecl()->setNothrow();
13917   }
13918 
13919   OMPLoopBasedDirective::HelperExprs B;
13920   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13921   // define the nested loops number.
13922   unsigned NestedLoopCount = checkOpenMPLoop(
13923       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13924       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13925       VarsWithImplicitDSA, B);
13926   if (NestedLoopCount == 0)
13927     return StmtError();
13928 
13929   assert((CurContext->isDependentContext() || B.builtAll()) &&
13930          "omp for loop exprs were not built");
13931 
13932   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13933   // The grainsize clause and num_tasks clause are mutually exclusive and may
13934   // not appear on the same taskloop directive.
13935   if (checkMutuallyExclusiveClauses(*this, Clauses,
13936                                     {OMPC_grainsize, OMPC_num_tasks}))
13937     return StmtError();
13938   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13939   // If a reduction clause is present on the taskloop directive, the nogroup
13940   // clause must not be specified.
13941   if (checkReductionClauseWithNogroup(*this, Clauses))
13942     return StmtError();
13943 
13944   setFunctionHasBranchProtectedScope();
13945   return OMPParallelMasterTaskLoopDirective::Create(
13946       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13947       DSAStack->isCancelRegion());
13948 }
13949 
ActOnOpenMPParallelMaskedTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)13950 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13951     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13952     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13953   if (!AStmt)
13954     return StmtError();
13955 
13956   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13957   auto *CS = cast<CapturedStmt>(AStmt);
13958   // 1.2.2 OpenMP Language Terminology
13959   // Structured block - An executable statement with a single entry at the
13960   // top and a single exit at the bottom.
13961   // The point of exit cannot be a branch out of the structured block.
13962   // longjmp() and throw() must not violate the entry/exit criteria.
13963   CS->getCapturedDecl()->setNothrow();
13964   for (int ThisCaptureLevel =
13965            getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13966        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13967     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13968     // 1.2.2 OpenMP Language Terminology
13969     // Structured block - An executable statement with a single entry at the
13970     // top and a single exit at the bottom.
13971     // The point of exit cannot be a branch out of the structured block.
13972     // longjmp() and throw() must not violate the entry/exit criteria.
13973     CS->getCapturedDecl()->setNothrow();
13974   }
13975 
13976   OMPLoopBasedDirective::HelperExprs B;
13977   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13978   // define the nested loops number.
13979   unsigned NestedLoopCount = checkOpenMPLoop(
13980       OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13981       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13982       VarsWithImplicitDSA, B);
13983   if (NestedLoopCount == 0)
13984     return StmtError();
13985 
13986   assert((CurContext->isDependentContext() || B.builtAll()) &&
13987          "omp for loop exprs were not built");
13988 
13989   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13990   // The grainsize clause and num_tasks clause are mutually exclusive and may
13991   // not appear on the same taskloop directive.
13992   if (checkMutuallyExclusiveClauses(*this, Clauses,
13993                                     {OMPC_grainsize, OMPC_num_tasks}))
13994     return StmtError();
13995   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13996   // If a reduction clause is present on the taskloop directive, the nogroup
13997   // clause must not be specified.
13998   if (checkReductionClauseWithNogroup(*this, Clauses))
13999     return StmtError();
14000 
14001   setFunctionHasBranchProtectedScope();
14002   return OMPParallelMaskedTaskLoopDirective::Create(
14003       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14004       DSAStack->isCancelRegion());
14005 }
14006 
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14007 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
14008     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14009     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14010   if (!AStmt)
14011     return StmtError();
14012 
14013   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14014   auto *CS = cast<CapturedStmt>(AStmt);
14015   // 1.2.2 OpenMP Language Terminology
14016   // Structured block - An executable statement with a single entry at the
14017   // top and a single exit at the bottom.
14018   // The point of exit cannot be a branch out of the structured block.
14019   // longjmp() and throw() must not violate the entry/exit criteria.
14020   CS->getCapturedDecl()->setNothrow();
14021   for (int ThisCaptureLevel =
14022            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
14023        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14024     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14025     // 1.2.2 OpenMP Language Terminology
14026     // Structured block - An executable statement with a single entry at the
14027     // top and a single exit at the bottom.
14028     // The point of exit cannot be a branch out of the structured block.
14029     // longjmp() and throw() must not violate the entry/exit criteria.
14030     CS->getCapturedDecl()->setNothrow();
14031   }
14032 
14033   OMPLoopBasedDirective::HelperExprs B;
14034   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14035   // define the nested loops number.
14036   unsigned NestedLoopCount = checkOpenMPLoop(
14037       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
14038       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14039       VarsWithImplicitDSA, B);
14040   if (NestedLoopCount == 0)
14041     return StmtError();
14042 
14043   assert((CurContext->isDependentContext() || B.builtAll()) &&
14044          "omp for loop exprs were not built");
14045 
14046   if (!CurContext->isDependentContext()) {
14047     // Finalize the clauses that need pre-built expressions for CodeGen.
14048     for (OMPClause *C : Clauses) {
14049       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14050         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14051                                      B.NumIterations, *this, CurScope,
14052                                      DSAStack))
14053           return StmtError();
14054     }
14055   }
14056 
14057   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14058   // The grainsize clause and num_tasks clause are mutually exclusive and may
14059   // not appear on the same taskloop directive.
14060   if (checkMutuallyExclusiveClauses(*this, Clauses,
14061                                     {OMPC_grainsize, OMPC_num_tasks}))
14062     return StmtError();
14063   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14064   // If a reduction clause is present on the taskloop directive, the nogroup
14065   // clause must not be specified.
14066   if (checkReductionClauseWithNogroup(*this, Clauses))
14067     return StmtError();
14068   if (checkSimdlenSafelenSpecified(*this, Clauses))
14069     return StmtError();
14070 
14071   setFunctionHasBranchProtectedScope();
14072   return OMPParallelMasterTaskLoopSimdDirective::Create(
14073       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14074 }
14075 
ActOnOpenMPParallelMaskedTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14076 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
14077     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14078     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14079   if (!AStmt)
14080     return StmtError();
14081 
14082   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14083   auto *CS = cast<CapturedStmt>(AStmt);
14084   // 1.2.2 OpenMP Language Terminology
14085   // Structured block - An executable statement with a single entry at the
14086   // top and a single exit at the bottom.
14087   // The point of exit cannot be a branch out of the structured block.
14088   // longjmp() and throw() must not violate the entry/exit criteria.
14089   CS->getCapturedDecl()->setNothrow();
14090   for (int ThisCaptureLevel =
14091            getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
14092        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14093     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14094     // 1.2.2 OpenMP Language Terminology
14095     // Structured block - An executable statement with a single entry at the
14096     // top and a single exit at the bottom.
14097     // The point of exit cannot be a branch out of the structured block.
14098     // longjmp() and throw() must not violate the entry/exit criteria.
14099     CS->getCapturedDecl()->setNothrow();
14100   }
14101 
14102   OMPLoopBasedDirective::HelperExprs B;
14103   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14104   // define the nested loops number.
14105   unsigned NestedLoopCount = checkOpenMPLoop(
14106       OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
14107       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14108       VarsWithImplicitDSA, B);
14109   if (NestedLoopCount == 0)
14110     return StmtError();
14111 
14112   assert((CurContext->isDependentContext() || B.builtAll()) &&
14113          "omp for loop exprs were not built");
14114 
14115   if (!CurContext->isDependentContext()) {
14116     // Finalize the clauses that need pre-built expressions for CodeGen.
14117     for (OMPClause *C : Clauses) {
14118       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14119         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14120                                      B.NumIterations, *this, CurScope,
14121                                      DSAStack))
14122           return StmtError();
14123     }
14124   }
14125 
14126   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14127   // The grainsize clause and num_tasks clause are mutually exclusive and may
14128   // not appear on the same taskloop directive.
14129   if (checkMutuallyExclusiveClauses(*this, Clauses,
14130                                     {OMPC_grainsize, OMPC_num_tasks}))
14131     return StmtError();
14132   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14133   // If a reduction clause is present on the taskloop directive, the nogroup
14134   // clause must not be specified.
14135   if (checkReductionClauseWithNogroup(*this, Clauses))
14136     return StmtError();
14137   if (checkSimdlenSafelenSpecified(*this, Clauses))
14138     return StmtError();
14139 
14140   setFunctionHasBranchProtectedScope();
14141   return OMPParallelMaskedTaskLoopSimdDirective::Create(
14142       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14143 }
14144 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14145 StmtResult Sema::ActOnOpenMPDistributeDirective(
14146     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14147     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14148   if (!AStmt)
14149     return StmtError();
14150 
14151   if (!checkLastPrivateForMappedDirectives(Clauses))
14152     return StmtError();
14153 
14154   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14155   OMPLoopBasedDirective::HelperExprs B;
14156   // In presence of clause 'collapse' with number of loops, it will
14157   // define the nested loops number.
14158   unsigned NestedLoopCount =
14159       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
14160                       nullptr /*ordered not a clause on distribute*/, AStmt,
14161                       *this, *DSAStack, VarsWithImplicitDSA, B);
14162   if (NestedLoopCount == 0)
14163     return StmtError();
14164 
14165   assert((CurContext->isDependentContext() || B.builtAll()) &&
14166          "omp for loop exprs were not built");
14167 
14168   setFunctionHasBranchProtectedScope();
14169   auto *DistributeDirective = OMPDistributeDirective::Create(
14170       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14171       DSAStack->getMappedDirective());
14172   return DistributeDirective;
14173 }
14174 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14175 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
14176     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14177     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14178   if (!AStmt)
14179     return StmtError();
14180 
14181   auto *CS = cast<CapturedStmt>(AStmt);
14182   // 1.2.2 OpenMP Language Terminology
14183   // Structured block - An executable statement with a single entry at the
14184   // top and a single exit at the bottom.
14185   // The point of exit cannot be a branch out of the structured block.
14186   // longjmp() and throw() must not violate the entry/exit criteria.
14187   CS->getCapturedDecl()->setNothrow();
14188   for (int ThisCaptureLevel =
14189            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
14190        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14191     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14192     // 1.2.2 OpenMP Language Terminology
14193     // Structured block - An executable statement with a single entry at the
14194     // top and a single exit at the bottom.
14195     // The point of exit cannot be a branch out of the structured block.
14196     // longjmp() and throw() must not violate the entry/exit criteria.
14197     CS->getCapturedDecl()->setNothrow();
14198   }
14199 
14200   OMPLoopBasedDirective::HelperExprs B;
14201   // In presence of clause 'collapse' with number of loops, it will
14202   // define the nested loops number.
14203   unsigned NestedLoopCount = checkOpenMPLoop(
14204       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14205       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14206       VarsWithImplicitDSA, B);
14207   if (NestedLoopCount == 0)
14208     return StmtError();
14209 
14210   assert((CurContext->isDependentContext() || B.builtAll()) &&
14211          "omp for loop exprs were not built");
14212 
14213   setFunctionHasBranchProtectedScope();
14214   return OMPDistributeParallelForDirective::Create(
14215       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14216       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14217 }
14218 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14219 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
14220     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14221     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14222   if (!AStmt)
14223     return StmtError();
14224 
14225   auto *CS = cast<CapturedStmt>(AStmt);
14226   // 1.2.2 OpenMP Language Terminology
14227   // Structured block - An executable statement with a single entry at the
14228   // top and a single exit at the bottom.
14229   // The point of exit cannot be a branch out of the structured block.
14230   // longjmp() and throw() must not violate the entry/exit criteria.
14231   CS->getCapturedDecl()->setNothrow();
14232   for (int ThisCaptureLevel =
14233            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
14234        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14235     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14236     // 1.2.2 OpenMP Language Terminology
14237     // Structured block - An executable statement with a single entry at the
14238     // top and a single exit at the bottom.
14239     // The point of exit cannot be a branch out of the structured block.
14240     // longjmp() and throw() must not violate the entry/exit criteria.
14241     CS->getCapturedDecl()->setNothrow();
14242   }
14243 
14244   OMPLoopBasedDirective::HelperExprs B;
14245   // In presence of clause 'collapse' with number of loops, it will
14246   // define the nested loops number.
14247   unsigned NestedLoopCount = checkOpenMPLoop(
14248       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14249       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14250       VarsWithImplicitDSA, B);
14251   if (NestedLoopCount == 0)
14252     return StmtError();
14253 
14254   assert((CurContext->isDependentContext() || B.builtAll()) &&
14255          "omp for loop exprs were not built");
14256 
14257   if (!CurContext->isDependentContext()) {
14258     // Finalize the clauses that need pre-built expressions for CodeGen.
14259     for (OMPClause *C : Clauses) {
14260       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14261         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14262                                      B.NumIterations, *this, CurScope,
14263                                      DSAStack))
14264           return StmtError();
14265     }
14266   }
14267 
14268   if (checkSimdlenSafelenSpecified(*this, Clauses))
14269     return StmtError();
14270 
14271   setFunctionHasBranchProtectedScope();
14272   return OMPDistributeParallelForSimdDirective::Create(
14273       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14274 }
14275 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14276 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
14277     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14278     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14279   if (!AStmt)
14280     return StmtError();
14281 
14282   auto *CS = cast<CapturedStmt>(AStmt);
14283   // 1.2.2 OpenMP Language Terminology
14284   // Structured block - An executable statement with a single entry at the
14285   // top and a single exit at the bottom.
14286   // The point of exit cannot be a branch out of the structured block.
14287   // longjmp() and throw() must not violate the entry/exit criteria.
14288   CS->getCapturedDecl()->setNothrow();
14289   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
14290        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14291     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14292     // 1.2.2 OpenMP Language Terminology
14293     // Structured block - An executable statement with a single entry at the
14294     // top and a single exit at the bottom.
14295     // The point of exit cannot be a branch out of the structured block.
14296     // longjmp() and throw() must not violate the entry/exit criteria.
14297     CS->getCapturedDecl()->setNothrow();
14298   }
14299 
14300   OMPLoopBasedDirective::HelperExprs B;
14301   // In presence of clause 'collapse' with number of loops, it will
14302   // define the nested loops number.
14303   unsigned NestedLoopCount =
14304       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
14305                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14306                       *DSAStack, VarsWithImplicitDSA, B);
14307   if (NestedLoopCount == 0)
14308     return StmtError();
14309 
14310   assert((CurContext->isDependentContext() || B.builtAll()) &&
14311          "omp for loop exprs were not built");
14312 
14313   if (!CurContext->isDependentContext()) {
14314     // Finalize the clauses that need pre-built expressions for CodeGen.
14315     for (OMPClause *C : Clauses) {
14316       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14317         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14318                                      B.NumIterations, *this, CurScope,
14319                                      DSAStack))
14320           return StmtError();
14321     }
14322   }
14323 
14324   if (checkSimdlenSafelenSpecified(*this, Clauses))
14325     return StmtError();
14326 
14327   setFunctionHasBranchProtectedScope();
14328   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14329                                             NestedLoopCount, Clauses, AStmt, B);
14330 }
14331 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14332 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
14333     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14334     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14335   if (!AStmt)
14336     return StmtError();
14337 
14338   auto *CS = cast<CapturedStmt>(AStmt);
14339   // 1.2.2 OpenMP Language Terminology
14340   // Structured block - An executable statement with a single entry at the
14341   // top and a single exit at the bottom.
14342   // The point of exit cannot be a branch out of the structured block.
14343   // longjmp() and throw() must not violate the entry/exit criteria.
14344   CS->getCapturedDecl()->setNothrow();
14345   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14346        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14347     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14348     // 1.2.2 OpenMP Language Terminology
14349     // Structured block - An executable statement with a single entry at the
14350     // top and a single exit at the bottom.
14351     // The point of exit cannot be a branch out of the structured block.
14352     // longjmp() and throw() must not violate the entry/exit criteria.
14353     CS->getCapturedDecl()->setNothrow();
14354   }
14355 
14356   OMPLoopBasedDirective::HelperExprs B;
14357   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14358   // define the nested loops number.
14359   unsigned NestedLoopCount = checkOpenMPLoop(
14360       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14361       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
14362       B);
14363   if (NestedLoopCount == 0)
14364     return StmtError();
14365 
14366   assert((CurContext->isDependentContext() || B.builtAll()) &&
14367          "omp target parallel for simd loop exprs were not built");
14368 
14369   if (!CurContext->isDependentContext()) {
14370     // Finalize the clauses that need pre-built expressions for CodeGen.
14371     for (OMPClause *C : Clauses) {
14372       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14373         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14374                                      B.NumIterations, *this, CurScope,
14375                                      DSAStack))
14376           return StmtError();
14377     }
14378   }
14379   if (checkSimdlenSafelenSpecified(*this, Clauses))
14380     return StmtError();
14381 
14382   setFunctionHasBranchProtectedScope();
14383   return OMPTargetParallelForSimdDirective::Create(
14384       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14385 }
14386 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14387 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
14388     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14389     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14390   if (!AStmt)
14391     return StmtError();
14392 
14393   auto *CS = cast<CapturedStmt>(AStmt);
14394   // 1.2.2 OpenMP Language Terminology
14395   // Structured block - An executable statement with a single entry at the
14396   // top and a single exit at the bottom.
14397   // The point of exit cannot be a branch out of the structured block.
14398   // longjmp() and throw() must not violate the entry/exit criteria.
14399   CS->getCapturedDecl()->setNothrow();
14400   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14401        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14402     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14403     // 1.2.2 OpenMP Language Terminology
14404     // Structured block - An executable statement with a single entry at the
14405     // top and a single exit at the bottom.
14406     // The point of exit cannot be a branch out of the structured block.
14407     // longjmp() and throw() must not violate the entry/exit criteria.
14408     CS->getCapturedDecl()->setNothrow();
14409   }
14410 
14411   OMPLoopBasedDirective::HelperExprs B;
14412   // In presence of clause 'collapse' with number of loops, it will define the
14413   // nested loops number.
14414   unsigned NestedLoopCount =
14415       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14416                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
14417                       VarsWithImplicitDSA, B);
14418   if (NestedLoopCount == 0)
14419     return StmtError();
14420 
14421   assert((CurContext->isDependentContext() || B.builtAll()) &&
14422          "omp target simd loop exprs were not built");
14423 
14424   if (!CurContext->isDependentContext()) {
14425     // Finalize the clauses that need pre-built expressions for CodeGen.
14426     for (OMPClause *C : Clauses) {
14427       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14428         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14429                                      B.NumIterations, *this, CurScope,
14430                                      DSAStack))
14431           return StmtError();
14432     }
14433   }
14434 
14435   if (checkSimdlenSafelenSpecified(*this, Clauses))
14436     return StmtError();
14437 
14438   setFunctionHasBranchProtectedScope();
14439   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14440                                         NestedLoopCount, Clauses, AStmt, B);
14441 }
14442 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14443 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14444     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14445     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14446   if (!AStmt)
14447     return StmtError();
14448 
14449   auto *CS = cast<CapturedStmt>(AStmt);
14450   // 1.2.2 OpenMP Language Terminology
14451   // Structured block - An executable statement with a single entry at the
14452   // top and a single exit at the bottom.
14453   // The point of exit cannot be a branch out of the structured block.
14454   // longjmp() and throw() must not violate the entry/exit criteria.
14455   CS->getCapturedDecl()->setNothrow();
14456   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14457        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14458     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14459     // 1.2.2 OpenMP Language Terminology
14460     // Structured block - An executable statement with a single entry at the
14461     // top and a single exit at the bottom.
14462     // The point of exit cannot be a branch out of the structured block.
14463     // longjmp() and throw() must not violate the entry/exit criteria.
14464     CS->getCapturedDecl()->setNothrow();
14465   }
14466 
14467   OMPLoopBasedDirective::HelperExprs B;
14468   // In presence of clause 'collapse' with number of loops, it will
14469   // define the nested loops number.
14470   unsigned NestedLoopCount =
14471       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14472                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14473                       *DSAStack, VarsWithImplicitDSA, B);
14474   if (NestedLoopCount == 0)
14475     return StmtError();
14476 
14477   assert((CurContext->isDependentContext() || B.builtAll()) &&
14478          "omp teams distribute loop exprs were not built");
14479 
14480   setFunctionHasBranchProtectedScope();
14481 
14482   DSAStack->setParentTeamsRegionLoc(StartLoc);
14483 
14484   return OMPTeamsDistributeDirective::Create(
14485       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14486 }
14487 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14488 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14489     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14490     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14491   if (!AStmt)
14492     return StmtError();
14493 
14494   auto *CS = cast<CapturedStmt>(AStmt);
14495   // 1.2.2 OpenMP Language Terminology
14496   // Structured block - An executable statement with a single entry at the
14497   // top and a single exit at the bottom.
14498   // The point of exit cannot be a branch out of the structured block.
14499   // longjmp() and throw() must not violate the entry/exit criteria.
14500   CS->getCapturedDecl()->setNothrow();
14501   for (int ThisCaptureLevel =
14502            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14503        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14504     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14505     // 1.2.2 OpenMP Language Terminology
14506     // Structured block - An executable statement with a single entry at the
14507     // top and a single exit at the bottom.
14508     // The point of exit cannot be a branch out of the structured block.
14509     // longjmp() and throw() must not violate the entry/exit criteria.
14510     CS->getCapturedDecl()->setNothrow();
14511   }
14512 
14513   OMPLoopBasedDirective::HelperExprs B;
14514   // In presence of clause 'collapse' with number of loops, it will
14515   // define the nested loops number.
14516   unsigned NestedLoopCount = checkOpenMPLoop(
14517       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14518       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14519       VarsWithImplicitDSA, B);
14520 
14521   if (NestedLoopCount == 0)
14522     return StmtError();
14523 
14524   assert((CurContext->isDependentContext() || B.builtAll()) &&
14525          "omp teams distribute simd loop exprs were not built");
14526 
14527   if (!CurContext->isDependentContext()) {
14528     // Finalize the clauses that need pre-built expressions for CodeGen.
14529     for (OMPClause *C : Clauses) {
14530       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14531         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14532                                      B.NumIterations, *this, CurScope,
14533                                      DSAStack))
14534           return StmtError();
14535     }
14536   }
14537 
14538   if (checkSimdlenSafelenSpecified(*this, Clauses))
14539     return StmtError();
14540 
14541   setFunctionHasBranchProtectedScope();
14542 
14543   DSAStack->setParentTeamsRegionLoc(StartLoc);
14544 
14545   return OMPTeamsDistributeSimdDirective::Create(
14546       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14547 }
14548 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14549 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14550     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14551     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14552   if (!AStmt)
14553     return StmtError();
14554 
14555   auto *CS = cast<CapturedStmt>(AStmt);
14556   // 1.2.2 OpenMP Language Terminology
14557   // Structured block - An executable statement with a single entry at the
14558   // top and a single exit at the bottom.
14559   // The point of exit cannot be a branch out of the structured block.
14560   // longjmp() and throw() must not violate the entry/exit criteria.
14561   CS->getCapturedDecl()->setNothrow();
14562 
14563   for (int ThisCaptureLevel =
14564            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14565        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14566     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14567     // 1.2.2 OpenMP Language Terminology
14568     // Structured block - An executable statement with a single entry at the
14569     // top and a single exit at the bottom.
14570     // The point of exit cannot be a branch out of the structured block.
14571     // longjmp() and throw() must not violate the entry/exit criteria.
14572     CS->getCapturedDecl()->setNothrow();
14573   }
14574 
14575   OMPLoopBasedDirective::HelperExprs B;
14576   // In presence of clause 'collapse' with number of loops, it will
14577   // define the nested loops number.
14578   unsigned NestedLoopCount = checkOpenMPLoop(
14579       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14580       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14581       VarsWithImplicitDSA, B);
14582 
14583   if (NestedLoopCount == 0)
14584     return StmtError();
14585 
14586   assert((CurContext->isDependentContext() || B.builtAll()) &&
14587          "omp for loop exprs were not built");
14588 
14589   if (!CurContext->isDependentContext()) {
14590     // Finalize the clauses that need pre-built expressions for CodeGen.
14591     for (OMPClause *C : Clauses) {
14592       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14593         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14594                                      B.NumIterations, *this, CurScope,
14595                                      DSAStack))
14596           return StmtError();
14597     }
14598   }
14599 
14600   if (checkSimdlenSafelenSpecified(*this, Clauses))
14601     return StmtError();
14602 
14603   setFunctionHasBranchProtectedScope();
14604 
14605   DSAStack->setParentTeamsRegionLoc(StartLoc);
14606 
14607   return OMPTeamsDistributeParallelForSimdDirective::Create(
14608       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14609 }
14610 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14611 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14612     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14613     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14614   if (!AStmt)
14615     return StmtError();
14616 
14617   auto *CS = cast<CapturedStmt>(AStmt);
14618   // 1.2.2 OpenMP Language Terminology
14619   // Structured block - An executable statement with a single entry at the
14620   // top and a single exit at the bottom.
14621   // The point of exit cannot be a branch out of the structured block.
14622   // longjmp() and throw() must not violate the entry/exit criteria.
14623   CS->getCapturedDecl()->setNothrow();
14624 
14625   for (int ThisCaptureLevel =
14626            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14627        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14628     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14629     // 1.2.2 OpenMP Language Terminology
14630     // Structured block - An executable statement with a single entry at the
14631     // top and a single exit at the bottom.
14632     // The point of exit cannot be a branch out of the structured block.
14633     // longjmp() and throw() must not violate the entry/exit criteria.
14634     CS->getCapturedDecl()->setNothrow();
14635   }
14636 
14637   OMPLoopBasedDirective::HelperExprs B;
14638   // In presence of clause 'collapse' with number of loops, it will
14639   // define the nested loops number.
14640   unsigned NestedLoopCount = checkOpenMPLoop(
14641       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14642       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14643       VarsWithImplicitDSA, B);
14644 
14645   if (NestedLoopCount == 0)
14646     return StmtError();
14647 
14648   assert((CurContext->isDependentContext() || B.builtAll()) &&
14649          "omp for loop exprs were not built");
14650 
14651   setFunctionHasBranchProtectedScope();
14652 
14653   DSAStack->setParentTeamsRegionLoc(StartLoc);
14654 
14655   return OMPTeamsDistributeParallelForDirective::Create(
14656       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14657       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14658 }
14659 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)14660 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14661                                                  Stmt *AStmt,
14662                                                  SourceLocation StartLoc,
14663                                                  SourceLocation EndLoc) {
14664   if (!AStmt)
14665     return StmtError();
14666 
14667   auto *CS = cast<CapturedStmt>(AStmt);
14668   // 1.2.2 OpenMP Language Terminology
14669   // Structured block - An executable statement with a single entry at the
14670   // top and a single exit at the bottom.
14671   // The point of exit cannot be a branch out of the structured block.
14672   // longjmp() and throw() must not violate the entry/exit criteria.
14673   CS->getCapturedDecl()->setNothrow();
14674 
14675   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14676        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14677     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14678     // 1.2.2 OpenMP Language Terminology
14679     // Structured block - An executable statement with a single entry at the
14680     // top and a single exit at the bottom.
14681     // The point of exit cannot be a branch out of the structured block.
14682     // longjmp() and throw() must not violate the entry/exit criteria.
14683     CS->getCapturedDecl()->setNothrow();
14684   }
14685   setFunctionHasBranchProtectedScope();
14686 
14687   const OMPClause *BareClause = nullptr;
14688   bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) &&
14689                                          hasClauses(Clauses, OMPC_thread_limit);
14690   bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) {
14691     BareClause = C;
14692     return C->getClauseKind() == OMPC_ompx_bare;
14693   });
14694 
14695   if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
14696     Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid);
14697     return StmtError();
14698   }
14699 
14700   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14701                                          AStmt);
14702 }
14703 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14704 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14705     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14706     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14707   if (!AStmt)
14708     return StmtError();
14709 
14710   auto *CS = cast<CapturedStmt>(AStmt);
14711   // 1.2.2 OpenMP Language Terminology
14712   // Structured block - An executable statement with a single entry at the
14713   // top and a single exit at the bottom.
14714   // The point of exit cannot be a branch out of the structured block.
14715   // longjmp() and throw() must not violate the entry/exit criteria.
14716   CS->getCapturedDecl()->setNothrow();
14717   for (int ThisCaptureLevel =
14718            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14719        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14720     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14721     // 1.2.2 OpenMP Language Terminology
14722     // Structured block - An executable statement with a single entry at the
14723     // top and a single exit at the bottom.
14724     // The point of exit cannot be a branch out of the structured block.
14725     // longjmp() and throw() must not violate the entry/exit criteria.
14726     CS->getCapturedDecl()->setNothrow();
14727   }
14728 
14729   OMPLoopBasedDirective::HelperExprs B;
14730   // In presence of clause 'collapse' with number of loops, it will
14731   // define the nested loops number.
14732   unsigned NestedLoopCount = checkOpenMPLoop(
14733       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14734       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14735       VarsWithImplicitDSA, B);
14736   if (NestedLoopCount == 0)
14737     return StmtError();
14738 
14739   assert((CurContext->isDependentContext() || B.builtAll()) &&
14740          "omp target teams distribute loop exprs were not built");
14741 
14742   setFunctionHasBranchProtectedScope();
14743   return OMPTargetTeamsDistributeDirective::Create(
14744       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14745 }
14746 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14747 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14748     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14749     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14750   if (!AStmt)
14751     return StmtError();
14752 
14753   auto *CS = cast<CapturedStmt>(AStmt);
14754   // 1.2.2 OpenMP Language Terminology
14755   // Structured block - An executable statement with a single entry at the
14756   // top and a single exit at the bottom.
14757   // The point of exit cannot be a branch out of the structured block.
14758   // longjmp() and throw() must not violate the entry/exit criteria.
14759   CS->getCapturedDecl()->setNothrow();
14760   for (int ThisCaptureLevel =
14761            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14762        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14763     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14764     // 1.2.2 OpenMP Language Terminology
14765     // Structured block - An executable statement with a single entry at the
14766     // top and a single exit at the bottom.
14767     // The point of exit cannot be a branch out of the structured block.
14768     // longjmp() and throw() must not violate the entry/exit criteria.
14769     CS->getCapturedDecl()->setNothrow();
14770   }
14771 
14772   OMPLoopBasedDirective::HelperExprs B;
14773   // In presence of clause 'collapse' with number of loops, it will
14774   // define the nested loops number.
14775   unsigned NestedLoopCount = checkOpenMPLoop(
14776       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14777       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14778       VarsWithImplicitDSA, B);
14779   if (NestedLoopCount == 0)
14780     return StmtError();
14781 
14782   assert((CurContext->isDependentContext() || B.builtAll()) &&
14783          "omp target teams distribute parallel for loop exprs were not built");
14784 
14785   if (!CurContext->isDependentContext()) {
14786     // Finalize the clauses that need pre-built expressions for CodeGen.
14787     for (OMPClause *C : Clauses) {
14788       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14789         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14790                                      B.NumIterations, *this, CurScope,
14791                                      DSAStack))
14792           return StmtError();
14793     }
14794   }
14795 
14796   setFunctionHasBranchProtectedScope();
14797   return OMPTargetTeamsDistributeParallelForDirective::Create(
14798       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14799       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14800 }
14801 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14802 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14803     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14804     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14805   if (!AStmt)
14806     return StmtError();
14807 
14808   auto *CS = cast<CapturedStmt>(AStmt);
14809   // 1.2.2 OpenMP Language Terminology
14810   // Structured block - An executable statement with a single entry at the
14811   // top and a single exit at the bottom.
14812   // The point of exit cannot be a branch out of the structured block.
14813   // longjmp() and throw() must not violate the entry/exit criteria.
14814   CS->getCapturedDecl()->setNothrow();
14815   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14816            OMPD_target_teams_distribute_parallel_for_simd);
14817        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14818     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14819     // 1.2.2 OpenMP Language Terminology
14820     // Structured block - An executable statement with a single entry at the
14821     // top and a single exit at the bottom.
14822     // The point of exit cannot be a branch out of the structured block.
14823     // longjmp() and throw() must not violate the entry/exit criteria.
14824     CS->getCapturedDecl()->setNothrow();
14825   }
14826 
14827   OMPLoopBasedDirective::HelperExprs B;
14828   // In presence of clause 'collapse' with number of loops, it will
14829   // define the nested loops number.
14830   unsigned NestedLoopCount =
14831       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14832                       getCollapseNumberExpr(Clauses),
14833                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14834                       *DSAStack, VarsWithImplicitDSA, B);
14835   if (NestedLoopCount == 0)
14836     return StmtError();
14837 
14838   assert((CurContext->isDependentContext() || B.builtAll()) &&
14839          "omp target teams distribute parallel for simd loop exprs were not "
14840          "built");
14841 
14842   if (!CurContext->isDependentContext()) {
14843     // Finalize the clauses that need pre-built expressions for CodeGen.
14844     for (OMPClause *C : Clauses) {
14845       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14846         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14847                                      B.NumIterations, *this, CurScope,
14848                                      DSAStack))
14849           return StmtError();
14850     }
14851   }
14852 
14853   if (checkSimdlenSafelenSpecified(*this, Clauses))
14854     return StmtError();
14855 
14856   setFunctionHasBranchProtectedScope();
14857   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14858       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14859 }
14860 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)14861 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14862     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14863     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14864   if (!AStmt)
14865     return StmtError();
14866 
14867   auto *CS = cast<CapturedStmt>(AStmt);
14868   // 1.2.2 OpenMP Language Terminology
14869   // Structured block - An executable statement with a single entry at the
14870   // top and a single exit at the bottom.
14871   // The point of exit cannot be a branch out of the structured block.
14872   // longjmp() and throw() must not violate the entry/exit criteria.
14873   CS->getCapturedDecl()->setNothrow();
14874   for (int ThisCaptureLevel =
14875            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14876        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14877     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14878     // 1.2.2 OpenMP Language Terminology
14879     // Structured block - An executable statement with a single entry at the
14880     // top and a single exit at the bottom.
14881     // The point of exit cannot be a branch out of the structured block.
14882     // longjmp() and throw() must not violate the entry/exit criteria.
14883     CS->getCapturedDecl()->setNothrow();
14884   }
14885 
14886   OMPLoopBasedDirective::HelperExprs B;
14887   // In presence of clause 'collapse' with number of loops, it will
14888   // define the nested loops number.
14889   unsigned NestedLoopCount = checkOpenMPLoop(
14890       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14891       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14892       VarsWithImplicitDSA, B);
14893   if (NestedLoopCount == 0)
14894     return StmtError();
14895 
14896   assert((CurContext->isDependentContext() || B.builtAll()) &&
14897          "omp target teams distribute simd loop exprs were not built");
14898 
14899   if (!CurContext->isDependentContext()) {
14900     // Finalize the clauses that need pre-built expressions for CodeGen.
14901     for (OMPClause *C : Clauses) {
14902       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14903         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14904                                      B.NumIterations, *this, CurScope,
14905                                      DSAStack))
14906           return StmtError();
14907     }
14908   }
14909 
14910   if (checkSimdlenSafelenSpecified(*this, Clauses))
14911     return StmtError();
14912 
14913   setFunctionHasBranchProtectedScope();
14914   return OMPTargetTeamsDistributeSimdDirective::Create(
14915       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14916 }
14917 
checkTransformableLoopNest(OpenMPDirectiveKind Kind,Stmt * AStmt,int NumLoops,SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> & LoopHelpers,Stmt * & Body,SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *,Decl * >,0>> & OriginalInits)14918 bool Sema::checkTransformableLoopNest(
14919     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14920     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14921     Stmt *&Body,
14922     SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14923         &OriginalInits) {
14924   OriginalInits.emplace_back();
14925   bool Result = OMPLoopBasedDirective::doForAllLoops(
14926       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14927       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14928                                                         Stmt *CurStmt) {
14929         VarsWithInheritedDSAType TmpDSA;
14930         unsigned SingleNumLoops =
14931             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14932                             TmpDSA, LoopHelpers[Cnt]);
14933         if (SingleNumLoops == 0)
14934           return true;
14935         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14936         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14937           OriginalInits.back().push_back(For->getInit());
14938           Body = For->getBody();
14939         } else {
14940           assert(isa<CXXForRangeStmt>(CurStmt) &&
14941                  "Expected canonical for or range-based for loops.");
14942           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14943           OriginalInits.back().push_back(CXXFor->getBeginStmt());
14944           Body = CXXFor->getBody();
14945         }
14946         OriginalInits.emplace_back();
14947         return false;
14948       },
14949       [&OriginalInits](OMPLoopBasedDirective *Transform) {
14950         Stmt *DependentPreInits;
14951         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14952           DependentPreInits = Dir->getPreInits();
14953         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14954           DependentPreInits = Dir->getPreInits();
14955         else
14956           llvm_unreachable("Unhandled loop transformation");
14957         if (!DependentPreInits)
14958           return;
14959         llvm::append_range(OriginalInits.back(),
14960                            cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14961       });
14962   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14963   OriginalInits.pop_back();
14964   return Result;
14965 }
14966 
ActOnOpenMPTileDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)14967 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14968                                           Stmt *AStmt, SourceLocation StartLoc,
14969                                           SourceLocation EndLoc) {
14970   auto SizesClauses =
14971       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14972   if (SizesClauses.empty()) {
14973     // A missing 'sizes' clause is already reported by the parser.
14974     return StmtError();
14975   }
14976   const OMPSizesClause *SizesClause = *SizesClauses.begin();
14977   unsigned NumLoops = SizesClause->getNumSizes();
14978 
14979   // Empty statement should only be possible if there already was an error.
14980   if (!AStmt)
14981     return StmtError();
14982 
14983   // Verify and diagnose loop nest.
14984   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14985   Stmt *Body = nullptr;
14986   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14987       OriginalInits;
14988   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14989                                   OriginalInits))
14990     return StmtError();
14991 
14992   // Delay tiling to when template is completely instantiated.
14993   if (CurContext->isDependentContext())
14994     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14995                                     NumLoops, AStmt, nullptr, nullptr);
14996 
14997   SmallVector<Decl *, 4> PreInits;
14998 
14999   // Create iteration variables for the generated loops.
15000   SmallVector<VarDecl *, 4> FloorIndVars;
15001   SmallVector<VarDecl *, 4> TileIndVars;
15002   FloorIndVars.resize(NumLoops);
15003   TileIndVars.resize(NumLoops);
15004   for (unsigned I = 0; I < NumLoops; ++I) {
15005     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15006 
15007     assert(LoopHelper.Counters.size() == 1 &&
15008            "Expect single-dimensional loop iteration space");
15009     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15010     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15011     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15012     QualType CntTy = IterVarRef->getType();
15013 
15014     // Iteration variable for the floor (i.e. outer) loop.
15015     {
15016       std::string FloorCntName =
15017           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
15018       VarDecl *FloorCntDecl =
15019           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
15020       FloorIndVars[I] = FloorCntDecl;
15021     }
15022 
15023     // Iteration variable for the tile (i.e. inner) loop.
15024     {
15025       std::string TileCntName =
15026           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
15027 
15028       // Reuse the iteration variable created by checkOpenMPLoop. It is also
15029       // used by the expressions to derive the original iteration variable's
15030       // value from the logical iteration number.
15031       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
15032       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
15033       TileIndVars[I] = TileCntDecl;
15034     }
15035     for (auto &P : OriginalInits[I]) {
15036       if (auto *D = P.dyn_cast<Decl *>())
15037         PreInits.push_back(D);
15038       else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15039         PreInits.append(PI->decl_begin(), PI->decl_end());
15040     }
15041     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15042       PreInits.append(PI->decl_begin(), PI->decl_end());
15043     // Gather declarations for the data members used as counters.
15044     for (Expr *CounterRef : LoopHelper.Counters) {
15045       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15046       if (isa<OMPCapturedExprDecl>(CounterDecl))
15047         PreInits.push_back(CounterDecl);
15048     }
15049   }
15050 
15051   // Once the original iteration values are set, append the innermost body.
15052   Stmt *Inner = Body;
15053 
15054   // Create tile loops from the inside to the outside.
15055   for (int I = NumLoops - 1; I >= 0; --I) {
15056     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15057     Expr *NumIterations = LoopHelper.NumIterations;
15058     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15059     QualType CntTy = OrigCntVar->getType();
15060     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15061     Scope *CurScope = getCurScope();
15062 
15063     // Commonly used variables.
15064     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
15065                                            OrigCntVar->getExprLoc());
15066     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15067                                             OrigCntVar->getExprLoc());
15068 
15069     // For init-statement: auto .tile.iv = .floor.iv
15070     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
15071                          /*DirectInit=*/false);
15072     Decl *CounterDecl = TileIndVars[I];
15073     StmtResult InitStmt = new (Context)
15074         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15075                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15076     if (!InitStmt.isUsable())
15077       return StmtError();
15078 
15079     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
15080     // NumIterations)
15081     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15082                                       BO_Add, FloorIV, DimTileSize);
15083     if (!EndOfTile.isUsable())
15084       return StmtError();
15085     ExprResult IsPartialTile =
15086         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
15087                    NumIterations, EndOfTile.get());
15088     if (!IsPartialTile.isUsable())
15089       return StmtError();
15090     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
15091         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
15092         IsPartialTile.get(), NumIterations, EndOfTile.get());
15093     if (!MinTileAndIterSpace.isUsable())
15094       return StmtError();
15095     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15096                                      BO_LT, TileIV, MinTileAndIterSpace.get());
15097     if (!CondExpr.isUsable())
15098       return StmtError();
15099 
15100     // For incr-statement: ++.tile.iv
15101     ExprResult IncrStmt =
15102         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
15103     if (!IncrStmt.isUsable())
15104       return StmtError();
15105 
15106     // Statements to set the original iteration variable's value from the
15107     // logical iteration number.
15108     // Generated for loop is:
15109     // Original_for_init;
15110     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
15111     // NumIterations); ++.tile.iv) {
15112     //   Original_Body;
15113     //   Original_counter_update;
15114     // }
15115     // FIXME: If the innermost body is an loop itself, inserting these
15116     // statements stops it being recognized  as a perfectly nested loop (e.g.
15117     // for applying tiling again). If this is the case, sink the expressions
15118     // further into the inner loop.
15119     SmallVector<Stmt *, 4> BodyParts;
15120     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15121     BodyParts.push_back(Inner);
15122     Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
15123                                  Inner->getBeginLoc(), Inner->getEndLoc());
15124     Inner = new (Context)
15125         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15126                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15127                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15128   }
15129 
15130   // Create floor loops from the inside to the outside.
15131   for (int I = NumLoops - 1; I >= 0; --I) {
15132     auto &LoopHelper = LoopHelpers[I];
15133     Expr *NumIterations = LoopHelper.NumIterations;
15134     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15135     QualType CntTy = OrigCntVar->getType();
15136     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15137     Scope *CurScope = getCurScope();
15138 
15139     // Commonly used variables.
15140     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15141                                             OrigCntVar->getExprLoc());
15142 
15143     // For init-statement: auto .floor.iv = 0
15144     AddInitializerToDecl(
15145         FloorIndVars[I],
15146         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15147         /*DirectInit=*/false);
15148     Decl *CounterDecl = FloorIndVars[I];
15149     StmtResult InitStmt = new (Context)
15150         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15151                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15152     if (!InitStmt.isUsable())
15153       return StmtError();
15154 
15155     // For cond-expression: .floor.iv < NumIterations
15156     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15157                                      BO_LT, FloorIV, NumIterations);
15158     if (!CondExpr.isUsable())
15159       return StmtError();
15160 
15161     // For incr-statement: .floor.iv += DimTileSize
15162     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
15163                                      BO_AddAssign, FloorIV, DimTileSize);
15164     if (!IncrStmt.isUsable())
15165       return StmtError();
15166 
15167     Inner = new (Context)
15168         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15169                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15170                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15171   }
15172 
15173   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
15174                                   AStmt, Inner,
15175                                   buildPreInits(Context, PreInits));
15176 }
15177 
ActOnOpenMPUnrollDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)15178 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
15179                                             Stmt *AStmt,
15180                                             SourceLocation StartLoc,
15181                                             SourceLocation EndLoc) {
15182   // Empty statement should only be possible if there already was an error.
15183   if (!AStmt)
15184     return StmtError();
15185 
15186   if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
15187     return StmtError();
15188 
15189   const OMPFullClause *FullClause =
15190       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15191   const OMPPartialClause *PartialClause =
15192       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15193   assert(!(FullClause && PartialClause) &&
15194          "mutual exclusivity must have been checked before");
15195 
15196   constexpr unsigned NumLoops = 1;
15197   Stmt *Body = nullptr;
15198   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
15199       NumLoops);
15200   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
15201       OriginalInits;
15202   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15203                                   Body, OriginalInits))
15204     return StmtError();
15205 
15206   unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
15207 
15208   // Delay unrolling to when template is completely instantiated.
15209   if (CurContext->isDependentContext())
15210     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15211                                       NumGeneratedLoops, nullptr, nullptr);
15212 
15213   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
15214 
15215   if (FullClause) {
15216     if (!VerifyPositiveIntegerConstantInClause(
15217              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
15218              /*SuppressExprDiags=*/true)
15219              .isUsable()) {
15220       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15221       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
15222           << "#pragma omp unroll full";
15223       return StmtError();
15224     }
15225   }
15226 
15227   // The generated loop may only be passed to other loop-associated directive
15228   // when a partial clause is specified. Without the requirement it is
15229   // sufficient to generate loop unroll metadata at code-generation.
15230   if (NumGeneratedLoops == 0)
15231     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15232                                       NumGeneratedLoops, nullptr, nullptr);
15233 
15234   // Otherwise, we need to provide a de-sugared/transformed AST that can be
15235   // associated with another loop directive.
15236   //
15237   // The canonical loop analysis return by checkTransformableLoopNest assumes
15238   // the following structure to be the same loop without transformations or
15239   // directives applied: \code OriginalInits; LoopHelper.PreInits;
15240   // LoopHelper.Counters;
15241   // for (; IV < LoopHelper.NumIterations; ++IV) {
15242   //   LoopHelper.Updates;
15243   //   Body;
15244   // }
15245   // \endcode
15246   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
15247   // and referenced by LoopHelper.IterationVarRef.
15248   //
15249   // The unrolling directive transforms this into the following loop:
15250   // \code
15251   // OriginalInits;         \
15252   // LoopHelper.PreInits;    > NewPreInits
15253   // LoopHelper.Counters;   /
15254   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
15255   //   #pragma clang loop unroll_count(Factor)
15256   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
15257   //   {
15258   //     LoopHelper.Updates;
15259   //     Body;
15260   //   }
15261   // }
15262   // \endcode
15263   // where UIV is a new logical iteration counter. IV must be the same VarDecl
15264   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
15265   // references it. If the partially unrolled loop is associated with another
15266   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
15267   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
15268   // OpenMP canonical loop. The inner loop is not an associable canonical loop
15269   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
15270   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
15271   // property of the OMPLoopBasedDirective instead of statements in
15272   // CompoundStatement. This is to allow the loop to become a non-outermost loop
15273   // of a canonical loop nest where these PreInits are emitted before the
15274   // outermost directive.
15275 
15276   // Determine the PreInit declarations.
15277   SmallVector<Decl *, 4> PreInits;
15278   assert(OriginalInits.size() == 1 &&
15279          "Expecting a single-dimensional loop iteration space");
15280   for (auto &P : OriginalInits[0]) {
15281     if (auto *D = P.dyn_cast<Decl *>())
15282       PreInits.push_back(D);
15283     else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15284       PreInits.append(PI->decl_begin(), PI->decl_end());
15285   }
15286   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15287     PreInits.append(PI->decl_begin(), PI->decl_end());
15288   // Gather declarations for the data members used as counters.
15289   for (Expr *CounterRef : LoopHelper.Counters) {
15290     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15291     if (isa<OMPCapturedExprDecl>(CounterDecl))
15292       PreInits.push_back(CounterDecl);
15293   }
15294 
15295   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15296   QualType IVTy = IterationVarRef->getType();
15297   assert(LoopHelper.Counters.size() == 1 &&
15298          "Expecting a single-dimensional loop iteration space");
15299   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15300 
15301   // Determine the unroll factor.
15302   uint64_t Factor;
15303   SourceLocation FactorLoc;
15304   if (Expr *FactorVal = PartialClause->getFactor()) {
15305     Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15306     FactorLoc = FactorVal->getExprLoc();
15307   } else {
15308     // TODO: Use a better profitability model.
15309     Factor = 2;
15310   }
15311   assert(Factor > 0 && "Expected positive unroll factor");
15312   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
15313     return IntegerLiteral::Create(
15314         Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
15315         FactorLoc);
15316   };
15317 
15318   // Iteration variable SourceLocations.
15319   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
15320   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
15321   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
15322 
15323   // Internal variable names.
15324   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15325   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
15326   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
15327   std::string InnerTripCountName =
15328       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
15329 
15330   // Create the iteration variable for the unrolled loop.
15331   VarDecl *OuterIVDecl =
15332       buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15333   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15334     return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15335   };
15336 
15337   // Iteration variable for the inner loop: Reuse the iteration variable created
15338   // by checkOpenMPLoop.
15339   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15340   InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15341   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15342     return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15343   };
15344 
15345   // Make a copy of the NumIterations expression for each use: By the AST
15346   // constraints, every expression object in a DeclContext must be unique.
15347   CaptureVars CopyTransformer(*this);
15348   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15349     return AssertSuccess(
15350         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15351   };
15352 
15353   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15354   ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15355   AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15356   StmtResult InnerInit = new (Context)
15357       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15358   if (!InnerInit.isUsable())
15359     return StmtError();
15360 
15361   // Inner For cond-expression:
15362   // \code
15363   //   .unroll_inner.iv < .unrolled.iv + Factor &&
15364   //   .unroll_inner.iv < NumIterations
15365   // \endcode
15366   // This conjunction of two conditions allows ScalarEvolution to derive the
15367   // maximum trip count of the inner loop.
15368   ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15369                                     BO_Add, MakeOuterRef(), MakeFactorExpr());
15370   if (!EndOfTile.isUsable())
15371     return StmtError();
15372   ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15373                                      BO_LT, MakeInnerRef(), EndOfTile.get());
15374   if (!InnerCond1.isUsable())
15375     return StmtError();
15376   ExprResult InnerCond2 =
15377       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15378                  MakeNumIterations());
15379   if (!InnerCond2.isUsable())
15380     return StmtError();
15381   ExprResult InnerCond =
15382       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15383                  InnerCond1.get(), InnerCond2.get());
15384   if (!InnerCond.isUsable())
15385     return StmtError();
15386 
15387   // Inner For incr-statement: ++.unroll_inner.iv
15388   ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15389                                       UO_PreInc, MakeInnerRef());
15390   if (!InnerIncr.isUsable())
15391     return StmtError();
15392 
15393   // Inner For statement.
15394   SmallVector<Stmt *> InnerBodyStmts;
15395   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15396   InnerBodyStmts.push_back(Body);
15397   CompoundStmt *InnerBody =
15398       CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15399                            Body->getBeginLoc(), Body->getEndLoc());
15400   ForStmt *InnerFor = new (Context)
15401       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15402               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15403               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15404 
15405   // Unroll metadata for the inner loop.
15406   // This needs to take into account the remainder portion of the unrolled loop,
15407   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15408   // supports multiple loop exits. Instead, unroll using a factor equivalent to
15409   // the maximum trip count, which will also generate a remainder loop. Just
15410   // `unroll(enable)` (which could have been useful if the user has not
15411   // specified a concrete factor; even though the outer loop cannot be
15412   // influenced anymore, would avoid more code bloat than necessary) will refuse
15413   // the loop because "Won't unroll; remainder loop could not be generated when
15414   // assuming runtime trip count". Even if it did work, it must not choose a
15415   // larger unroll factor than the maximum loop length, or it would always just
15416   // execute the remainder loop.
15417   LoopHintAttr *UnrollHintAttr =
15418       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15419                                    LoopHintAttr::Numeric, MakeFactorExpr());
15420   AttributedStmt *InnerUnrolled =
15421       AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15422 
15423   // Outer For init-statement: auto .unrolled.iv = 0
15424   AddInitializerToDecl(
15425       OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15426       /*DirectInit=*/false);
15427   StmtResult OuterInit = new (Context)
15428       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15429   if (!OuterInit.isUsable())
15430     return StmtError();
15431 
15432   // Outer For cond-expression: .unrolled.iv < NumIterations
15433   ExprResult OuterConde =
15434       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15435                  MakeNumIterations());
15436   if (!OuterConde.isUsable())
15437     return StmtError();
15438 
15439   // Outer For incr-statement: .unrolled.iv += Factor
15440   ExprResult OuterIncr =
15441       BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15442                  MakeOuterRef(), MakeFactorExpr());
15443   if (!OuterIncr.isUsable())
15444     return StmtError();
15445 
15446   // Outer For statement.
15447   ForStmt *OuterFor = new (Context)
15448       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15449               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15450               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15451 
15452   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15453                                     NumGeneratedLoops, OuterFor,
15454                                     buildPreInits(Context, PreInits));
15455 }
15456 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15457 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15458                                              SourceLocation StartLoc,
15459                                              SourceLocation LParenLoc,
15460                                              SourceLocation EndLoc) {
15461   OMPClause *Res = nullptr;
15462   switch (Kind) {
15463   case OMPC_final:
15464     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15465     break;
15466   case OMPC_num_threads:
15467     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15468     break;
15469   case OMPC_safelen:
15470     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15471     break;
15472   case OMPC_simdlen:
15473     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15474     break;
15475   case OMPC_allocator:
15476     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15477     break;
15478   case OMPC_collapse:
15479     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15480     break;
15481   case OMPC_ordered:
15482     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15483     break;
15484   case OMPC_num_teams:
15485     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15486     break;
15487   case OMPC_thread_limit:
15488     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15489     break;
15490   case OMPC_priority:
15491     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15492     break;
15493   case OMPC_hint:
15494     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15495     break;
15496   case OMPC_depobj:
15497     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15498     break;
15499   case OMPC_detach:
15500     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15501     break;
15502   case OMPC_novariants:
15503     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15504     break;
15505   case OMPC_nocontext:
15506     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15507     break;
15508   case OMPC_filter:
15509     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15510     break;
15511   case OMPC_partial:
15512     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15513     break;
15514   case OMPC_message:
15515     Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15516     break;
15517   case OMPC_align:
15518     Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15519     break;
15520   case OMPC_ompx_dyn_cgroup_mem:
15521     Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15522     break;
15523   case OMPC_grainsize:
15524   case OMPC_num_tasks:
15525   case OMPC_device:
15526   case OMPC_if:
15527   case OMPC_default:
15528   case OMPC_proc_bind:
15529   case OMPC_schedule:
15530   case OMPC_private:
15531   case OMPC_firstprivate:
15532   case OMPC_lastprivate:
15533   case OMPC_shared:
15534   case OMPC_reduction:
15535   case OMPC_task_reduction:
15536   case OMPC_in_reduction:
15537   case OMPC_linear:
15538   case OMPC_aligned:
15539   case OMPC_copyin:
15540   case OMPC_copyprivate:
15541   case OMPC_nowait:
15542   case OMPC_untied:
15543   case OMPC_mergeable:
15544   case OMPC_threadprivate:
15545   case OMPC_sizes:
15546   case OMPC_allocate:
15547   case OMPC_flush:
15548   case OMPC_read:
15549   case OMPC_write:
15550   case OMPC_update:
15551   case OMPC_capture:
15552   case OMPC_compare:
15553   case OMPC_seq_cst:
15554   case OMPC_acq_rel:
15555   case OMPC_acquire:
15556   case OMPC_release:
15557   case OMPC_relaxed:
15558   case OMPC_depend:
15559   case OMPC_threads:
15560   case OMPC_simd:
15561   case OMPC_map:
15562   case OMPC_nogroup:
15563   case OMPC_dist_schedule:
15564   case OMPC_defaultmap:
15565   case OMPC_unknown:
15566   case OMPC_uniform:
15567   case OMPC_to:
15568   case OMPC_from:
15569   case OMPC_use_device_ptr:
15570   case OMPC_use_device_addr:
15571   case OMPC_is_device_ptr:
15572   case OMPC_unified_address:
15573   case OMPC_unified_shared_memory:
15574   case OMPC_reverse_offload:
15575   case OMPC_dynamic_allocators:
15576   case OMPC_atomic_default_mem_order:
15577   case OMPC_device_type:
15578   case OMPC_match:
15579   case OMPC_nontemporal:
15580   case OMPC_order:
15581   case OMPC_at:
15582   case OMPC_severity:
15583   case OMPC_destroy:
15584   case OMPC_inclusive:
15585   case OMPC_exclusive:
15586   case OMPC_uses_allocators:
15587   case OMPC_affinity:
15588   case OMPC_when:
15589   case OMPC_bind:
15590   default:
15591     llvm_unreachable("Clause is not allowed.");
15592   }
15593   return Res;
15594 }
15595 
15596 // An OpenMP directive such as 'target parallel' has two captured regions:
15597 // for the 'target' and 'parallel' respectively.  This function returns
15598 // the region in which to capture expressions associated with a clause.
15599 // A return value of OMPD_unknown signifies that the expression should not
15600 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)15601 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15602     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15603     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15604   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15605   switch (CKind) {
15606   case OMPC_if:
15607     switch (DKind) {
15608     case OMPD_target_parallel_for_simd:
15609       if (OpenMPVersion >= 50 &&
15610           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15611         CaptureRegion = OMPD_parallel;
15612         break;
15613       }
15614       [[fallthrough]];
15615     case OMPD_target_parallel:
15616     case OMPD_target_parallel_for:
15617     case OMPD_target_parallel_loop:
15618       // If this clause applies to the nested 'parallel' region, capture within
15619       // the 'target' region, otherwise do not capture.
15620       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15621         CaptureRegion = OMPD_target;
15622       break;
15623     case OMPD_target_teams_distribute_parallel_for_simd:
15624       if (OpenMPVersion >= 50 &&
15625           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15626         CaptureRegion = OMPD_parallel;
15627         break;
15628       }
15629       [[fallthrough]];
15630     case OMPD_target_teams_loop:
15631     case OMPD_target_teams_distribute_parallel_for:
15632       // If this clause applies to the nested 'parallel' region, capture within
15633       // the 'teams' region, otherwise do not capture.
15634       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15635         CaptureRegion = OMPD_teams;
15636       break;
15637     case OMPD_teams_distribute_parallel_for_simd:
15638       if (OpenMPVersion >= 50 &&
15639           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15640         CaptureRegion = OMPD_parallel;
15641         break;
15642       }
15643       [[fallthrough]];
15644     case OMPD_teams_distribute_parallel_for:
15645       CaptureRegion = OMPD_teams;
15646       break;
15647     case OMPD_target_update:
15648     case OMPD_target_enter_data:
15649     case OMPD_target_exit_data:
15650       CaptureRegion = OMPD_task;
15651       break;
15652     case OMPD_parallel_masked_taskloop:
15653       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15654         CaptureRegion = OMPD_parallel;
15655       break;
15656     case OMPD_parallel_master_taskloop:
15657       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15658         CaptureRegion = OMPD_parallel;
15659       break;
15660     case OMPD_parallel_masked_taskloop_simd:
15661       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15662           NameModifier == OMPD_taskloop) {
15663         CaptureRegion = OMPD_parallel;
15664         break;
15665       }
15666       if (OpenMPVersion <= 45)
15667         break;
15668       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15669         CaptureRegion = OMPD_taskloop;
15670       break;
15671     case OMPD_parallel_master_taskloop_simd:
15672       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15673           NameModifier == OMPD_taskloop) {
15674         CaptureRegion = OMPD_parallel;
15675         break;
15676       }
15677       if (OpenMPVersion <= 45)
15678         break;
15679       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15680         CaptureRegion = OMPD_taskloop;
15681       break;
15682     case OMPD_parallel_for_simd:
15683       if (OpenMPVersion <= 45)
15684         break;
15685       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15686         CaptureRegion = OMPD_parallel;
15687       break;
15688     case OMPD_taskloop_simd:
15689     case OMPD_master_taskloop_simd:
15690     case OMPD_masked_taskloop_simd:
15691       if (OpenMPVersion <= 45)
15692         break;
15693       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15694         CaptureRegion = OMPD_taskloop;
15695       break;
15696     case OMPD_distribute_parallel_for_simd:
15697       if (OpenMPVersion <= 45)
15698         break;
15699       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15700         CaptureRegion = OMPD_parallel;
15701       break;
15702     case OMPD_target_simd:
15703       if (OpenMPVersion >= 50 &&
15704           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15705         CaptureRegion = OMPD_target;
15706       break;
15707     case OMPD_teams_distribute_simd:
15708     case OMPD_target_teams_distribute_simd:
15709       if (OpenMPVersion >= 50 &&
15710           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15711         CaptureRegion = OMPD_teams;
15712       break;
15713     case OMPD_cancel:
15714     case OMPD_parallel:
15715     case OMPD_parallel_master:
15716     case OMPD_parallel_masked:
15717     case OMPD_parallel_sections:
15718     case OMPD_parallel_for:
15719     case OMPD_parallel_loop:
15720     case OMPD_target:
15721     case OMPD_target_teams:
15722     case OMPD_target_teams_distribute:
15723     case OMPD_distribute_parallel_for:
15724     case OMPD_task:
15725     case OMPD_taskloop:
15726     case OMPD_master_taskloop:
15727     case OMPD_masked_taskloop:
15728     case OMPD_target_data:
15729     case OMPD_simd:
15730     case OMPD_for_simd:
15731     case OMPD_distribute_simd:
15732       // Do not capture if-clause expressions.
15733       break;
15734     case OMPD_threadprivate:
15735     case OMPD_allocate:
15736     case OMPD_taskyield:
15737     case OMPD_error:
15738     case OMPD_barrier:
15739     case OMPD_taskwait:
15740     case OMPD_cancellation_point:
15741     case OMPD_flush:
15742     case OMPD_depobj:
15743     case OMPD_scan:
15744     case OMPD_declare_reduction:
15745     case OMPD_declare_mapper:
15746     case OMPD_declare_simd:
15747     case OMPD_declare_variant:
15748     case OMPD_begin_declare_variant:
15749     case OMPD_end_declare_variant:
15750     case OMPD_declare_target:
15751     case OMPD_end_declare_target:
15752     case OMPD_loop:
15753     case OMPD_teams_loop:
15754     case OMPD_teams:
15755     case OMPD_tile:
15756     case OMPD_unroll:
15757     case OMPD_for:
15758     case OMPD_sections:
15759     case OMPD_section:
15760     case OMPD_single:
15761     case OMPD_master:
15762     case OMPD_masked:
15763     case OMPD_critical:
15764     case OMPD_taskgroup:
15765     case OMPD_distribute:
15766     case OMPD_ordered:
15767     case OMPD_atomic:
15768     case OMPD_teams_distribute:
15769     case OMPD_requires:
15770     case OMPD_metadirective:
15771       llvm_unreachable("Unexpected OpenMP directive with if-clause");
15772     case OMPD_unknown:
15773     default:
15774       llvm_unreachable("Unknown OpenMP directive");
15775     }
15776     break;
15777   case OMPC_num_threads:
15778     switch (DKind) {
15779     case OMPD_target_parallel:
15780     case OMPD_target_parallel_for:
15781     case OMPD_target_parallel_for_simd:
15782     case OMPD_target_parallel_loop:
15783       CaptureRegion = OMPD_target;
15784       break;
15785     case OMPD_teams_distribute_parallel_for:
15786     case OMPD_teams_distribute_parallel_for_simd:
15787     case OMPD_target_teams_distribute_parallel_for:
15788     case OMPD_target_teams_distribute_parallel_for_simd:
15789       CaptureRegion = OMPD_teams;
15790       break;
15791     case OMPD_parallel:
15792     case OMPD_parallel_master:
15793     case OMPD_parallel_masked:
15794     case OMPD_parallel_sections:
15795     case OMPD_parallel_for:
15796     case OMPD_parallel_for_simd:
15797     case OMPD_parallel_loop:
15798     case OMPD_distribute_parallel_for:
15799     case OMPD_distribute_parallel_for_simd:
15800     case OMPD_parallel_master_taskloop:
15801     case OMPD_parallel_masked_taskloop:
15802     case OMPD_parallel_master_taskloop_simd:
15803     case OMPD_parallel_masked_taskloop_simd:
15804       // Do not capture num_threads-clause expressions.
15805       break;
15806     case OMPD_target_data:
15807     case OMPD_target_enter_data:
15808     case OMPD_target_exit_data:
15809     case OMPD_target_update:
15810     case OMPD_target:
15811     case OMPD_target_simd:
15812     case OMPD_target_teams:
15813     case OMPD_target_teams_distribute:
15814     case OMPD_target_teams_distribute_simd:
15815     case OMPD_cancel:
15816     case OMPD_task:
15817     case OMPD_taskloop:
15818     case OMPD_taskloop_simd:
15819     case OMPD_master_taskloop:
15820     case OMPD_masked_taskloop:
15821     case OMPD_master_taskloop_simd:
15822     case OMPD_masked_taskloop_simd:
15823     case OMPD_threadprivate:
15824     case OMPD_allocate:
15825     case OMPD_taskyield:
15826     case OMPD_error:
15827     case OMPD_barrier:
15828     case OMPD_taskwait:
15829     case OMPD_cancellation_point:
15830     case OMPD_flush:
15831     case OMPD_depobj:
15832     case OMPD_scan:
15833     case OMPD_declare_reduction:
15834     case OMPD_declare_mapper:
15835     case OMPD_declare_simd:
15836     case OMPD_declare_variant:
15837     case OMPD_begin_declare_variant:
15838     case OMPD_end_declare_variant:
15839     case OMPD_declare_target:
15840     case OMPD_end_declare_target:
15841     case OMPD_loop:
15842     case OMPD_teams_loop:
15843     case OMPD_target_teams_loop:
15844     case OMPD_teams:
15845     case OMPD_simd:
15846     case OMPD_tile:
15847     case OMPD_unroll:
15848     case OMPD_for:
15849     case OMPD_for_simd:
15850     case OMPD_sections:
15851     case OMPD_section:
15852     case OMPD_single:
15853     case OMPD_master:
15854     case OMPD_masked:
15855     case OMPD_critical:
15856     case OMPD_taskgroup:
15857     case OMPD_distribute:
15858     case OMPD_ordered:
15859     case OMPD_atomic:
15860     case OMPD_distribute_simd:
15861     case OMPD_teams_distribute:
15862     case OMPD_teams_distribute_simd:
15863     case OMPD_requires:
15864     case OMPD_metadirective:
15865       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15866     case OMPD_unknown:
15867     default:
15868       llvm_unreachable("Unknown OpenMP directive");
15869     }
15870     break;
15871   case OMPC_num_teams:
15872     switch (DKind) {
15873     case OMPD_target_teams:
15874     case OMPD_target_teams_distribute:
15875     case OMPD_target_teams_distribute_simd:
15876     case OMPD_target_teams_distribute_parallel_for:
15877     case OMPD_target_teams_distribute_parallel_for_simd:
15878     case OMPD_target_teams_loop:
15879       CaptureRegion = OMPD_target;
15880       break;
15881     case OMPD_teams_distribute_parallel_for:
15882     case OMPD_teams_distribute_parallel_for_simd:
15883     case OMPD_teams:
15884     case OMPD_teams_distribute:
15885     case OMPD_teams_distribute_simd:
15886     case OMPD_teams_loop:
15887       // Do not capture num_teams-clause expressions.
15888       break;
15889     case OMPD_distribute_parallel_for:
15890     case OMPD_distribute_parallel_for_simd:
15891     case OMPD_task:
15892     case OMPD_taskloop:
15893     case OMPD_taskloop_simd:
15894     case OMPD_master_taskloop:
15895     case OMPD_masked_taskloop:
15896     case OMPD_master_taskloop_simd:
15897     case OMPD_masked_taskloop_simd:
15898     case OMPD_parallel_master_taskloop:
15899     case OMPD_parallel_masked_taskloop:
15900     case OMPD_parallel_master_taskloop_simd:
15901     case OMPD_parallel_masked_taskloop_simd:
15902     case OMPD_target_data:
15903     case OMPD_target_enter_data:
15904     case OMPD_target_exit_data:
15905     case OMPD_target_update:
15906     case OMPD_cancel:
15907     case OMPD_parallel:
15908     case OMPD_parallel_master:
15909     case OMPD_parallel_masked:
15910     case OMPD_parallel_sections:
15911     case OMPD_parallel_for:
15912     case OMPD_parallel_for_simd:
15913     case OMPD_parallel_loop:
15914     case OMPD_target:
15915     case OMPD_target_simd:
15916     case OMPD_target_parallel:
15917     case OMPD_target_parallel_for:
15918     case OMPD_target_parallel_for_simd:
15919     case OMPD_target_parallel_loop:
15920     case OMPD_threadprivate:
15921     case OMPD_allocate:
15922     case OMPD_taskyield:
15923     case OMPD_error:
15924     case OMPD_barrier:
15925     case OMPD_taskwait:
15926     case OMPD_cancellation_point:
15927     case OMPD_flush:
15928     case OMPD_depobj:
15929     case OMPD_scan:
15930     case OMPD_declare_reduction:
15931     case OMPD_declare_mapper:
15932     case OMPD_declare_simd:
15933     case OMPD_declare_variant:
15934     case OMPD_begin_declare_variant:
15935     case OMPD_end_declare_variant:
15936     case OMPD_declare_target:
15937     case OMPD_end_declare_target:
15938     case OMPD_loop:
15939     case OMPD_simd:
15940     case OMPD_tile:
15941     case OMPD_unroll:
15942     case OMPD_for:
15943     case OMPD_for_simd:
15944     case OMPD_sections:
15945     case OMPD_section:
15946     case OMPD_single:
15947     case OMPD_master:
15948     case OMPD_masked:
15949     case OMPD_critical:
15950     case OMPD_taskgroup:
15951     case OMPD_distribute:
15952     case OMPD_ordered:
15953     case OMPD_atomic:
15954     case OMPD_distribute_simd:
15955     case OMPD_requires:
15956     case OMPD_metadirective:
15957       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15958     case OMPD_unknown:
15959     default:
15960       llvm_unreachable("Unknown OpenMP directive");
15961     }
15962     break;
15963   case OMPC_thread_limit:
15964     switch (DKind) {
15965     case OMPD_target:
15966     case OMPD_target_teams:
15967     case OMPD_target_teams_distribute:
15968     case OMPD_target_teams_distribute_simd:
15969     case OMPD_target_teams_distribute_parallel_for:
15970     case OMPD_target_teams_distribute_parallel_for_simd:
15971     case OMPD_target_teams_loop:
15972     case OMPD_target_simd:
15973     case OMPD_target_parallel:
15974     case OMPD_target_parallel_for:
15975     case OMPD_target_parallel_for_simd:
15976     case OMPD_target_parallel_loop:
15977       CaptureRegion = OMPD_target;
15978       break;
15979     case OMPD_teams_distribute_parallel_for:
15980     case OMPD_teams_distribute_parallel_for_simd:
15981     case OMPD_teams:
15982     case OMPD_teams_distribute:
15983     case OMPD_teams_distribute_simd:
15984     case OMPD_teams_loop:
15985       // Do not capture thread_limit-clause expressions.
15986       break;
15987     case OMPD_distribute_parallel_for:
15988     case OMPD_distribute_parallel_for_simd:
15989     case OMPD_task:
15990     case OMPD_taskloop:
15991     case OMPD_taskloop_simd:
15992     case OMPD_master_taskloop:
15993     case OMPD_masked_taskloop:
15994     case OMPD_master_taskloop_simd:
15995     case OMPD_masked_taskloop_simd:
15996     case OMPD_parallel_master_taskloop:
15997     case OMPD_parallel_masked_taskloop:
15998     case OMPD_parallel_master_taskloop_simd:
15999     case OMPD_parallel_masked_taskloop_simd:
16000     case OMPD_target_data:
16001     case OMPD_target_enter_data:
16002     case OMPD_target_exit_data:
16003     case OMPD_target_update:
16004     case OMPD_cancel:
16005     case OMPD_parallel:
16006     case OMPD_parallel_master:
16007     case OMPD_parallel_masked:
16008     case OMPD_parallel_sections:
16009     case OMPD_parallel_for:
16010     case OMPD_parallel_for_simd:
16011     case OMPD_parallel_loop:
16012     case OMPD_threadprivate:
16013     case OMPD_allocate:
16014     case OMPD_taskyield:
16015     case OMPD_error:
16016     case OMPD_barrier:
16017     case OMPD_taskwait:
16018     case OMPD_cancellation_point:
16019     case OMPD_flush:
16020     case OMPD_depobj:
16021     case OMPD_scan:
16022     case OMPD_declare_reduction:
16023     case OMPD_declare_mapper:
16024     case OMPD_declare_simd:
16025     case OMPD_declare_variant:
16026     case OMPD_begin_declare_variant:
16027     case OMPD_end_declare_variant:
16028     case OMPD_declare_target:
16029     case OMPD_end_declare_target:
16030     case OMPD_loop:
16031     case OMPD_simd:
16032     case OMPD_tile:
16033     case OMPD_unroll:
16034     case OMPD_for:
16035     case OMPD_for_simd:
16036     case OMPD_sections:
16037     case OMPD_section:
16038     case OMPD_single:
16039     case OMPD_master:
16040     case OMPD_masked:
16041     case OMPD_critical:
16042     case OMPD_taskgroup:
16043     case OMPD_distribute:
16044     case OMPD_ordered:
16045     case OMPD_atomic:
16046     case OMPD_distribute_simd:
16047     case OMPD_requires:
16048     case OMPD_metadirective:
16049       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
16050     case OMPD_unknown:
16051     default:
16052       llvm_unreachable("Unknown OpenMP directive");
16053     }
16054     break;
16055   case OMPC_schedule:
16056     switch (DKind) {
16057     case OMPD_parallel_for:
16058     case OMPD_parallel_for_simd:
16059     case OMPD_distribute_parallel_for:
16060     case OMPD_distribute_parallel_for_simd:
16061     case OMPD_teams_distribute_parallel_for:
16062     case OMPD_teams_distribute_parallel_for_simd:
16063     case OMPD_target_parallel_for:
16064     case OMPD_target_parallel_for_simd:
16065     case OMPD_target_teams_distribute_parallel_for:
16066     case OMPD_target_teams_distribute_parallel_for_simd:
16067       CaptureRegion = OMPD_parallel;
16068       break;
16069     case OMPD_for:
16070     case OMPD_for_simd:
16071       // Do not capture schedule-clause expressions.
16072       break;
16073     case OMPD_task:
16074     case OMPD_taskloop:
16075     case OMPD_taskloop_simd:
16076     case OMPD_master_taskloop:
16077     case OMPD_masked_taskloop:
16078     case OMPD_master_taskloop_simd:
16079     case OMPD_masked_taskloop_simd:
16080     case OMPD_parallel_master_taskloop:
16081     case OMPD_parallel_masked_taskloop:
16082     case OMPD_parallel_master_taskloop_simd:
16083     case OMPD_parallel_masked_taskloop_simd:
16084     case OMPD_target_data:
16085     case OMPD_target_enter_data:
16086     case OMPD_target_exit_data:
16087     case OMPD_target_update:
16088     case OMPD_teams:
16089     case OMPD_teams_distribute:
16090     case OMPD_teams_distribute_simd:
16091     case OMPD_target_teams_distribute:
16092     case OMPD_target_teams_distribute_simd:
16093     case OMPD_target:
16094     case OMPD_target_simd:
16095     case OMPD_target_parallel:
16096     case OMPD_cancel:
16097     case OMPD_parallel:
16098     case OMPD_parallel_master:
16099     case OMPD_parallel_masked:
16100     case OMPD_parallel_sections:
16101     case OMPD_threadprivate:
16102     case OMPD_allocate:
16103     case OMPD_taskyield:
16104     case OMPD_error:
16105     case OMPD_barrier:
16106     case OMPD_taskwait:
16107     case OMPD_cancellation_point:
16108     case OMPD_flush:
16109     case OMPD_depobj:
16110     case OMPD_scan:
16111     case OMPD_declare_reduction:
16112     case OMPD_declare_mapper:
16113     case OMPD_declare_simd:
16114     case OMPD_declare_variant:
16115     case OMPD_begin_declare_variant:
16116     case OMPD_end_declare_variant:
16117     case OMPD_declare_target:
16118     case OMPD_end_declare_target:
16119     case OMPD_loop:
16120     case OMPD_teams_loop:
16121     case OMPD_target_teams_loop:
16122     case OMPD_parallel_loop:
16123     case OMPD_target_parallel_loop:
16124     case OMPD_simd:
16125     case OMPD_tile:
16126     case OMPD_unroll:
16127     case OMPD_sections:
16128     case OMPD_section:
16129     case OMPD_single:
16130     case OMPD_master:
16131     case OMPD_masked:
16132     case OMPD_critical:
16133     case OMPD_taskgroup:
16134     case OMPD_distribute:
16135     case OMPD_ordered:
16136     case OMPD_atomic:
16137     case OMPD_distribute_simd:
16138     case OMPD_target_teams:
16139     case OMPD_requires:
16140     case OMPD_metadirective:
16141       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
16142     case OMPD_unknown:
16143     default:
16144       llvm_unreachable("Unknown OpenMP directive");
16145     }
16146     break;
16147   case OMPC_dist_schedule:
16148     switch (DKind) {
16149     case OMPD_teams_distribute_parallel_for:
16150     case OMPD_teams_distribute_parallel_for_simd:
16151     case OMPD_teams_distribute:
16152     case OMPD_teams_distribute_simd:
16153     case OMPD_target_teams_distribute_parallel_for:
16154     case OMPD_target_teams_distribute_parallel_for_simd:
16155     case OMPD_target_teams_distribute:
16156     case OMPD_target_teams_distribute_simd:
16157       CaptureRegion = OMPD_teams;
16158       break;
16159     case OMPD_distribute_parallel_for:
16160     case OMPD_distribute_parallel_for_simd:
16161     case OMPD_distribute:
16162     case OMPD_distribute_simd:
16163       // Do not capture dist_schedule-clause expressions.
16164       break;
16165     case OMPD_parallel_for:
16166     case OMPD_parallel_for_simd:
16167     case OMPD_target_parallel_for_simd:
16168     case OMPD_target_parallel_for:
16169     case OMPD_task:
16170     case OMPD_taskloop:
16171     case OMPD_taskloop_simd:
16172     case OMPD_master_taskloop:
16173     case OMPD_masked_taskloop:
16174     case OMPD_master_taskloop_simd:
16175     case OMPD_masked_taskloop_simd:
16176     case OMPD_parallel_master_taskloop:
16177     case OMPD_parallel_masked_taskloop:
16178     case OMPD_parallel_master_taskloop_simd:
16179     case OMPD_parallel_masked_taskloop_simd:
16180     case OMPD_target_data:
16181     case OMPD_target_enter_data:
16182     case OMPD_target_exit_data:
16183     case OMPD_target_update:
16184     case OMPD_teams:
16185     case OMPD_target:
16186     case OMPD_target_simd:
16187     case OMPD_target_parallel:
16188     case OMPD_cancel:
16189     case OMPD_parallel:
16190     case OMPD_parallel_master:
16191     case OMPD_parallel_masked:
16192     case OMPD_parallel_sections:
16193     case OMPD_threadprivate:
16194     case OMPD_allocate:
16195     case OMPD_taskyield:
16196     case OMPD_error:
16197     case OMPD_barrier:
16198     case OMPD_taskwait:
16199     case OMPD_cancellation_point:
16200     case OMPD_flush:
16201     case OMPD_depobj:
16202     case OMPD_scan:
16203     case OMPD_declare_reduction:
16204     case OMPD_declare_mapper:
16205     case OMPD_declare_simd:
16206     case OMPD_declare_variant:
16207     case OMPD_begin_declare_variant:
16208     case OMPD_end_declare_variant:
16209     case OMPD_declare_target:
16210     case OMPD_end_declare_target:
16211     case OMPD_loop:
16212     case OMPD_teams_loop:
16213     case OMPD_target_teams_loop:
16214     case OMPD_parallel_loop:
16215     case OMPD_target_parallel_loop:
16216     case OMPD_simd:
16217     case OMPD_tile:
16218     case OMPD_unroll:
16219     case OMPD_for:
16220     case OMPD_for_simd:
16221     case OMPD_sections:
16222     case OMPD_section:
16223     case OMPD_single:
16224     case OMPD_master:
16225     case OMPD_masked:
16226     case OMPD_critical:
16227     case OMPD_taskgroup:
16228     case OMPD_ordered:
16229     case OMPD_atomic:
16230     case OMPD_target_teams:
16231     case OMPD_requires:
16232     case OMPD_metadirective:
16233       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
16234     case OMPD_unknown:
16235     default:
16236       llvm_unreachable("Unknown OpenMP directive");
16237     }
16238     break;
16239   case OMPC_ompx_dyn_cgroup_mem:
16240     switch (DKind) {
16241     case OMPD_target:
16242     case OMPD_target_simd:
16243     case OMPD_target_teams:
16244     case OMPD_target_parallel:
16245     case OMPD_target_teams_distribute:
16246     case OMPD_target_teams_distribute_simd:
16247     case OMPD_target_parallel_for:
16248     case OMPD_target_parallel_for_simd:
16249     case OMPD_target_parallel_loop:
16250     case OMPD_target_teams_distribute_parallel_for:
16251     case OMPD_target_teams_distribute_parallel_for_simd:
16252     case OMPD_target_teams_loop:
16253       CaptureRegion = OMPD_target;
16254       break;
16255     default:
16256       llvm_unreachable("Unknown OpenMP directive");
16257     }
16258     break;
16259   case OMPC_device:
16260     switch (DKind) {
16261     case OMPD_target_update:
16262     case OMPD_target_enter_data:
16263     case OMPD_target_exit_data:
16264     case OMPD_target:
16265     case OMPD_target_simd:
16266     case OMPD_target_teams:
16267     case OMPD_target_parallel:
16268     case OMPD_target_teams_distribute:
16269     case OMPD_target_teams_distribute_simd:
16270     case OMPD_target_parallel_for:
16271     case OMPD_target_parallel_for_simd:
16272     case OMPD_target_parallel_loop:
16273     case OMPD_target_teams_distribute_parallel_for:
16274     case OMPD_target_teams_distribute_parallel_for_simd:
16275     case OMPD_target_teams_loop:
16276     case OMPD_dispatch:
16277       CaptureRegion = OMPD_task;
16278       break;
16279     case OMPD_target_data:
16280     case OMPD_interop:
16281       // Do not capture device-clause expressions.
16282       break;
16283     case OMPD_teams_distribute_parallel_for:
16284     case OMPD_teams_distribute_parallel_for_simd:
16285     case OMPD_teams:
16286     case OMPD_teams_distribute:
16287     case OMPD_teams_distribute_simd:
16288     case OMPD_distribute_parallel_for:
16289     case OMPD_distribute_parallel_for_simd:
16290     case OMPD_task:
16291     case OMPD_taskloop:
16292     case OMPD_taskloop_simd:
16293     case OMPD_master_taskloop:
16294     case OMPD_masked_taskloop:
16295     case OMPD_master_taskloop_simd:
16296     case OMPD_masked_taskloop_simd:
16297     case OMPD_parallel_master_taskloop:
16298     case OMPD_parallel_masked_taskloop:
16299     case OMPD_parallel_master_taskloop_simd:
16300     case OMPD_parallel_masked_taskloop_simd:
16301     case OMPD_cancel:
16302     case OMPD_parallel:
16303     case OMPD_parallel_master:
16304     case OMPD_parallel_masked:
16305     case OMPD_parallel_sections:
16306     case OMPD_parallel_for:
16307     case OMPD_parallel_for_simd:
16308     case OMPD_threadprivate:
16309     case OMPD_allocate:
16310     case OMPD_taskyield:
16311     case OMPD_error:
16312     case OMPD_barrier:
16313     case OMPD_taskwait:
16314     case OMPD_cancellation_point:
16315     case OMPD_flush:
16316     case OMPD_depobj:
16317     case OMPD_scan:
16318     case OMPD_declare_reduction:
16319     case OMPD_declare_mapper:
16320     case OMPD_declare_simd:
16321     case OMPD_declare_variant:
16322     case OMPD_begin_declare_variant:
16323     case OMPD_end_declare_variant:
16324     case OMPD_declare_target:
16325     case OMPD_end_declare_target:
16326     case OMPD_loop:
16327     case OMPD_teams_loop:
16328     case OMPD_parallel_loop:
16329     case OMPD_simd:
16330     case OMPD_tile:
16331     case OMPD_unroll:
16332     case OMPD_for:
16333     case OMPD_for_simd:
16334     case OMPD_sections:
16335     case OMPD_section:
16336     case OMPD_single:
16337     case OMPD_master:
16338     case OMPD_masked:
16339     case OMPD_critical:
16340     case OMPD_taskgroup:
16341     case OMPD_distribute:
16342     case OMPD_ordered:
16343     case OMPD_atomic:
16344     case OMPD_distribute_simd:
16345     case OMPD_requires:
16346     case OMPD_metadirective:
16347       llvm_unreachable("Unexpected OpenMP directive with device-clause");
16348     case OMPD_unknown:
16349     default:
16350       llvm_unreachable("Unknown OpenMP directive");
16351     }
16352     break;
16353   case OMPC_grainsize:
16354   case OMPC_num_tasks:
16355   case OMPC_final:
16356   case OMPC_priority:
16357     switch (DKind) {
16358     case OMPD_task:
16359     case OMPD_taskloop:
16360     case OMPD_taskloop_simd:
16361     case OMPD_master_taskloop:
16362     case OMPD_masked_taskloop:
16363     case OMPD_master_taskloop_simd:
16364     case OMPD_masked_taskloop_simd:
16365       break;
16366     case OMPD_parallel_masked_taskloop:
16367     case OMPD_parallel_masked_taskloop_simd:
16368     case OMPD_parallel_master_taskloop:
16369     case OMPD_parallel_master_taskloop_simd:
16370       CaptureRegion = OMPD_parallel;
16371       break;
16372     case OMPD_target_update:
16373     case OMPD_target_enter_data:
16374     case OMPD_target_exit_data:
16375     case OMPD_target:
16376     case OMPD_target_simd:
16377     case OMPD_target_teams:
16378     case OMPD_target_parallel:
16379     case OMPD_target_teams_distribute:
16380     case OMPD_target_teams_distribute_simd:
16381     case OMPD_target_parallel_for:
16382     case OMPD_target_parallel_for_simd:
16383     case OMPD_target_teams_distribute_parallel_for:
16384     case OMPD_target_teams_distribute_parallel_for_simd:
16385     case OMPD_target_data:
16386     case OMPD_teams_distribute_parallel_for:
16387     case OMPD_teams_distribute_parallel_for_simd:
16388     case OMPD_teams:
16389     case OMPD_teams_distribute:
16390     case OMPD_teams_distribute_simd:
16391     case OMPD_distribute_parallel_for:
16392     case OMPD_distribute_parallel_for_simd:
16393     case OMPD_cancel:
16394     case OMPD_parallel:
16395     case OMPD_parallel_master:
16396     case OMPD_parallel_masked:
16397     case OMPD_parallel_sections:
16398     case OMPD_parallel_for:
16399     case OMPD_parallel_for_simd:
16400     case OMPD_threadprivate:
16401     case OMPD_allocate:
16402     case OMPD_taskyield:
16403     case OMPD_error:
16404     case OMPD_barrier:
16405     case OMPD_taskwait:
16406     case OMPD_cancellation_point:
16407     case OMPD_flush:
16408     case OMPD_depobj:
16409     case OMPD_scan:
16410     case OMPD_declare_reduction:
16411     case OMPD_declare_mapper:
16412     case OMPD_declare_simd:
16413     case OMPD_declare_variant:
16414     case OMPD_begin_declare_variant:
16415     case OMPD_end_declare_variant:
16416     case OMPD_declare_target:
16417     case OMPD_end_declare_target:
16418     case OMPD_loop:
16419     case OMPD_teams_loop:
16420     case OMPD_target_teams_loop:
16421     case OMPD_parallel_loop:
16422     case OMPD_target_parallel_loop:
16423     case OMPD_simd:
16424     case OMPD_tile:
16425     case OMPD_unroll:
16426     case OMPD_for:
16427     case OMPD_for_simd:
16428     case OMPD_sections:
16429     case OMPD_section:
16430     case OMPD_single:
16431     case OMPD_master:
16432     case OMPD_masked:
16433     case OMPD_critical:
16434     case OMPD_taskgroup:
16435     case OMPD_distribute:
16436     case OMPD_ordered:
16437     case OMPD_atomic:
16438     case OMPD_distribute_simd:
16439     case OMPD_requires:
16440     case OMPD_metadirective:
16441       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
16442     case OMPD_unknown:
16443     default:
16444       llvm_unreachable("Unknown OpenMP directive");
16445     }
16446     break;
16447   case OMPC_novariants:
16448   case OMPC_nocontext:
16449     switch (DKind) {
16450     case OMPD_dispatch:
16451       CaptureRegion = OMPD_task;
16452       break;
16453     default:
16454       llvm_unreachable("Unexpected OpenMP directive");
16455     }
16456     break;
16457   case OMPC_filter:
16458     // Do not capture filter-clause expressions.
16459     break;
16460   case OMPC_when:
16461     if (DKind == OMPD_metadirective) {
16462       CaptureRegion = OMPD_metadirective;
16463     } else if (DKind == OMPD_unknown) {
16464       llvm_unreachable("Unknown OpenMP directive");
16465     } else {
16466       llvm_unreachable("Unexpected OpenMP directive with when clause");
16467     }
16468     break;
16469   case OMPC_firstprivate:
16470   case OMPC_lastprivate:
16471   case OMPC_reduction:
16472   case OMPC_task_reduction:
16473   case OMPC_in_reduction:
16474   case OMPC_linear:
16475   case OMPC_default:
16476   case OMPC_proc_bind:
16477   case OMPC_safelen:
16478   case OMPC_simdlen:
16479   case OMPC_sizes:
16480   case OMPC_allocator:
16481   case OMPC_collapse:
16482   case OMPC_private:
16483   case OMPC_shared:
16484   case OMPC_aligned:
16485   case OMPC_copyin:
16486   case OMPC_copyprivate:
16487   case OMPC_ordered:
16488   case OMPC_nowait:
16489   case OMPC_untied:
16490   case OMPC_mergeable:
16491   case OMPC_threadprivate:
16492   case OMPC_allocate:
16493   case OMPC_flush:
16494   case OMPC_depobj:
16495   case OMPC_read:
16496   case OMPC_write:
16497   case OMPC_update:
16498   case OMPC_capture:
16499   case OMPC_compare:
16500   case OMPC_seq_cst:
16501   case OMPC_acq_rel:
16502   case OMPC_acquire:
16503   case OMPC_release:
16504   case OMPC_relaxed:
16505   case OMPC_depend:
16506   case OMPC_threads:
16507   case OMPC_simd:
16508   case OMPC_map:
16509   case OMPC_nogroup:
16510   case OMPC_hint:
16511   case OMPC_defaultmap:
16512   case OMPC_unknown:
16513   case OMPC_uniform:
16514   case OMPC_to:
16515   case OMPC_from:
16516   case OMPC_use_device_ptr:
16517   case OMPC_use_device_addr:
16518   case OMPC_is_device_ptr:
16519   case OMPC_unified_address:
16520   case OMPC_unified_shared_memory:
16521   case OMPC_reverse_offload:
16522   case OMPC_dynamic_allocators:
16523   case OMPC_atomic_default_mem_order:
16524   case OMPC_device_type:
16525   case OMPC_match:
16526   case OMPC_nontemporal:
16527   case OMPC_order:
16528   case OMPC_at:
16529   case OMPC_severity:
16530   case OMPC_message:
16531   case OMPC_destroy:
16532   case OMPC_detach:
16533   case OMPC_inclusive:
16534   case OMPC_exclusive:
16535   case OMPC_uses_allocators:
16536   case OMPC_affinity:
16537   case OMPC_bind:
16538   default:
16539     llvm_unreachable("Unexpected OpenMP clause.");
16540   }
16541   return CaptureRegion;
16542 }
16543 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)16544 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16545                                      Expr *Condition, SourceLocation StartLoc,
16546                                      SourceLocation LParenLoc,
16547                                      SourceLocation NameModifierLoc,
16548                                      SourceLocation ColonLoc,
16549                                      SourceLocation EndLoc) {
16550   Expr *ValExpr = Condition;
16551   Stmt *HelperValStmt = nullptr;
16552   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16553   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16554       !Condition->isInstantiationDependent() &&
16555       !Condition->containsUnexpandedParameterPack()) {
16556     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16557     if (Val.isInvalid())
16558       return nullptr;
16559 
16560     ValExpr = Val.get();
16561 
16562     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16563     CaptureRegion = getOpenMPCaptureRegionForClause(
16564         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16565     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16566       ValExpr = MakeFullExpr(ValExpr).get();
16567       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16568       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16569       HelperValStmt = buildPreInits(Context, Captures);
16570     }
16571   }
16572 
16573   return new (Context)
16574       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16575                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16576 }
16577 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16578 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16579                                         SourceLocation StartLoc,
16580                                         SourceLocation LParenLoc,
16581                                         SourceLocation EndLoc) {
16582   Expr *ValExpr = Condition;
16583   Stmt *HelperValStmt = nullptr;
16584   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16585   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16586       !Condition->isInstantiationDependent() &&
16587       !Condition->containsUnexpandedParameterPack()) {
16588     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16589     if (Val.isInvalid())
16590       return nullptr;
16591 
16592     ValExpr = MakeFullExpr(Val.get()).get();
16593 
16594     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16595     CaptureRegion =
16596         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16597     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16598       ValExpr = MakeFullExpr(ValExpr).get();
16599       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16600       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16601       HelperValStmt = buildPreInits(Context, Captures);
16602     }
16603   }
16604 
16605   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16606                                       StartLoc, LParenLoc, EndLoc);
16607 }
16608 
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)16609 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16610                                                         Expr *Op) {
16611   if (!Op)
16612     return ExprError();
16613 
16614   class IntConvertDiagnoser : public ICEConvertDiagnoser {
16615   public:
16616     IntConvertDiagnoser()
16617         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16618     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16619                                          QualType T) override {
16620       return S.Diag(Loc, diag::err_omp_not_integral) << T;
16621     }
16622     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16623                                              QualType T) override {
16624       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16625     }
16626     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16627                                                QualType T,
16628                                                QualType ConvTy) override {
16629       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16630     }
16631     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16632                                            QualType ConvTy) override {
16633       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16634              << ConvTy->isEnumeralType() << ConvTy;
16635     }
16636     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16637                                             QualType T) override {
16638       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16639     }
16640     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16641                                         QualType ConvTy) override {
16642       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16643              << ConvTy->isEnumeralType() << ConvTy;
16644     }
16645     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16646                                              QualType) override {
16647       llvm_unreachable("conversion functions are permitted");
16648     }
16649   } ConvertDiagnoser;
16650   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16651 }
16652 
16653 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)16654 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16655                           bool StrictlyPositive, bool BuildCapture = false,
16656                           OpenMPDirectiveKind DKind = OMPD_unknown,
16657                           OpenMPDirectiveKind *CaptureRegion = nullptr,
16658                           Stmt **HelperValStmt = nullptr) {
16659   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16660       !ValExpr->isInstantiationDependent()) {
16661     SourceLocation Loc = ValExpr->getExprLoc();
16662     ExprResult Value =
16663         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16664     if (Value.isInvalid())
16665       return false;
16666 
16667     ValExpr = Value.get();
16668     // The expression must evaluate to a non-negative integer value.
16669     if (std::optional<llvm::APSInt> Result =
16670             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16671       if (Result->isSigned() &&
16672           !((!StrictlyPositive && Result->isNonNegative()) ||
16673             (StrictlyPositive && Result->isStrictlyPositive()))) {
16674         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16675             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16676             << ValExpr->getSourceRange();
16677         return false;
16678       }
16679     }
16680     if (!BuildCapture)
16681       return true;
16682     *CaptureRegion =
16683         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16684     if (*CaptureRegion != OMPD_unknown &&
16685         !SemaRef.CurContext->isDependentContext()) {
16686       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16687       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16688       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16689       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16690     }
16691   }
16692   return true;
16693 }
16694 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16695 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16696                                              SourceLocation StartLoc,
16697                                              SourceLocation LParenLoc,
16698                                              SourceLocation EndLoc) {
16699   Expr *ValExpr = NumThreads;
16700   Stmt *HelperValStmt = nullptr;
16701 
16702   // OpenMP [2.5, Restrictions]
16703   //  The num_threads expression must evaluate to a positive integer value.
16704   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16705                                  /*StrictlyPositive=*/true))
16706     return nullptr;
16707 
16708   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16709   OpenMPDirectiveKind CaptureRegion =
16710       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16711   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16712     ValExpr = MakeFullExpr(ValExpr).get();
16713     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16714     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16715     HelperValStmt = buildPreInits(Context, Captures);
16716   }
16717 
16718   return new (Context) OMPNumThreadsClause(
16719       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16720 }
16721 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive,bool SuppressExprDiags)16722 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16723                                                        OpenMPClauseKind CKind,
16724                                                        bool StrictlyPositive,
16725                                                        bool SuppressExprDiags) {
16726   if (!E)
16727     return ExprError();
16728   if (E->isValueDependent() || E->isTypeDependent() ||
16729       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16730     return E;
16731 
16732   llvm::APSInt Result;
16733   ExprResult ICE;
16734   if (SuppressExprDiags) {
16735     // Use a custom diagnoser that suppresses 'note' diagnostics about the
16736     // expression.
16737     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16738       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16739       Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16740                                                  SourceLocation Loc) override {
16741         llvm_unreachable("Diagnostic suppressed");
16742       }
16743     } Diagnoser;
16744     ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16745   } else {
16746     ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16747   }
16748   if (ICE.isInvalid())
16749     return ExprError();
16750 
16751   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16752       (!StrictlyPositive && !Result.isNonNegative())) {
16753     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16754         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16755         << E->getSourceRange();
16756     return ExprError();
16757   }
16758   if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16759     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16760         << E->getSourceRange();
16761     return ExprError();
16762   }
16763   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
16764     DSAStack->setAssociatedLoops(Result.getExtValue());
16765   else if (CKind == OMPC_ordered)
16766     DSAStack->setAssociatedLoops(Result.getExtValue());
16767   return ICE;
16768 }
16769 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16770 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16771                                           SourceLocation LParenLoc,
16772                                           SourceLocation EndLoc) {
16773   // OpenMP [2.8.1, simd construct, Description]
16774   // The parameter of the safelen clause must be a constant
16775   // positive integer expression.
16776   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16777   if (Safelen.isInvalid())
16778     return nullptr;
16779   return new (Context)
16780       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16781 }
16782 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16783 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16784                                           SourceLocation LParenLoc,
16785                                           SourceLocation EndLoc) {
16786   // OpenMP [2.8.1, simd construct, Description]
16787   // The parameter of the simdlen clause must be a constant
16788   // positive integer expression.
16789   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16790   if (Simdlen.isInvalid())
16791     return nullptr;
16792   return new (Context)
16793       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16794 }
16795 
16796 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)16797 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16798                                     DSAStackTy *Stack) {
16799   if (!Stack->getOMPAllocatorHandleT().isNull())
16800     return true;
16801 
16802   // Set the allocator handle type.
16803   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
16804   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16805   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16806     S.Diag(Loc, diag::err_omp_implied_type_not_found)
16807         << "omp_allocator_handle_t";
16808     return false;
16809   }
16810   QualType AllocatorHandleEnumTy = PT.get();
16811   AllocatorHandleEnumTy.addConst();
16812   Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16813 
16814   // Fill the predefined allocator map.
16815   bool ErrorFound = false;
16816   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16817     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16818     StringRef Allocator =
16819         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16820     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16821     auto *VD = dyn_cast_or_null<ValueDecl>(
16822         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16823     if (!VD) {
16824       ErrorFound = true;
16825       break;
16826     }
16827     QualType AllocatorType =
16828         VD->getType().getNonLValueExprType(S.getASTContext());
16829     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16830     if (!Res.isUsable()) {
16831       ErrorFound = true;
16832       break;
16833     }
16834     Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
16835                                       Sema::AA_Initializing,
16836                                       /* AllowExplicit */ true);
16837     if (!Res.isUsable()) {
16838       ErrorFound = true;
16839       break;
16840     }
16841     Stack->setAllocator(AllocatorKind, Res.get());
16842   }
16843   if (ErrorFound) {
16844     S.Diag(Loc, diag::err_omp_implied_type_not_found)
16845         << "omp_allocator_handle_t";
16846     return false;
16847   }
16848 
16849   return true;
16850 }
16851 
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16852 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16853                                             SourceLocation LParenLoc,
16854                                             SourceLocation EndLoc) {
16855   // OpenMP [2.11.3, allocate Directive, Description]
16856   // allocator is an expression of omp_allocator_handle_t type.
16857   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16858     return nullptr;
16859 
16860   ExprResult Allocator = DefaultLvalueConversion(A);
16861   if (Allocator.isInvalid())
16862     return nullptr;
16863   Allocator = PerformImplicitConversion(Allocator.get(),
16864                                         DSAStack->getOMPAllocatorHandleT(),
16865                                         Sema::AA_Initializing,
16866                                         /*AllowExplicit=*/true);
16867   if (Allocator.isInvalid())
16868     return nullptr;
16869   return new (Context)
16870       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16871 }
16872 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16873 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16874                                            SourceLocation StartLoc,
16875                                            SourceLocation LParenLoc,
16876                                            SourceLocation EndLoc) {
16877   // OpenMP [2.7.1, loop construct, Description]
16878   // OpenMP [2.8.1, simd construct, Description]
16879   // OpenMP [2.9.6, distribute construct, Description]
16880   // The parameter of the collapse clause must be a constant
16881   // positive integer expression.
16882   ExprResult NumForLoopsResult =
16883       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16884   if (NumForLoopsResult.isInvalid())
16885     return nullptr;
16886   return new (Context)
16887       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16888 }
16889 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)16890 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16891                                           SourceLocation EndLoc,
16892                                           SourceLocation LParenLoc,
16893                                           Expr *NumForLoops) {
16894   // OpenMP [2.7.1, loop construct, Description]
16895   // OpenMP [2.8.1, simd construct, Description]
16896   // OpenMP [2.9.6, distribute construct, Description]
16897   // The parameter of the ordered clause must be a constant
16898   // positive integer expression if any.
16899   if (NumForLoops && LParenLoc.isValid()) {
16900     ExprResult NumForLoopsResult =
16901         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16902     if (NumForLoopsResult.isInvalid())
16903       return nullptr;
16904     NumForLoops = NumForLoopsResult.get();
16905   } else {
16906     NumForLoops = nullptr;
16907   }
16908   auto *Clause = OMPOrderedClause::Create(
16909       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
16910       StartLoc, LParenLoc, EndLoc);
16911   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16912   return Clause;
16913 }
16914 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16915 OMPClause *Sema::ActOnOpenMPSimpleClause(
16916     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16917     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16918   OMPClause *Res = nullptr;
16919   switch (Kind) {
16920   case OMPC_default:
16921     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16922                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16923     break;
16924   case OMPC_proc_bind:
16925     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16926                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16927     break;
16928   case OMPC_atomic_default_mem_order:
16929     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16930         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16931         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16932     break;
16933   case OMPC_fail:
16934     Res = ActOnOpenMPFailClause(
16935         static_cast<OpenMPClauseKind>(Argument),
16936         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16937     break;
16938   case OMPC_update:
16939     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16940                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16941     break;
16942   case OMPC_bind:
16943     Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16944                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16945     break;
16946   case OMPC_at:
16947     Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16948                               ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16949     break;
16950   case OMPC_severity:
16951     Res = ActOnOpenMPSeverityClause(
16952         static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16953         LParenLoc, EndLoc);
16954     break;
16955   case OMPC_if:
16956   case OMPC_final:
16957   case OMPC_num_threads:
16958   case OMPC_safelen:
16959   case OMPC_simdlen:
16960   case OMPC_sizes:
16961   case OMPC_allocator:
16962   case OMPC_collapse:
16963   case OMPC_schedule:
16964   case OMPC_private:
16965   case OMPC_firstprivate:
16966   case OMPC_lastprivate:
16967   case OMPC_shared:
16968   case OMPC_reduction:
16969   case OMPC_task_reduction:
16970   case OMPC_in_reduction:
16971   case OMPC_linear:
16972   case OMPC_aligned:
16973   case OMPC_copyin:
16974   case OMPC_copyprivate:
16975   case OMPC_ordered:
16976   case OMPC_nowait:
16977   case OMPC_untied:
16978   case OMPC_mergeable:
16979   case OMPC_threadprivate:
16980   case OMPC_allocate:
16981   case OMPC_flush:
16982   case OMPC_depobj:
16983   case OMPC_read:
16984   case OMPC_write:
16985   case OMPC_capture:
16986   case OMPC_compare:
16987   case OMPC_seq_cst:
16988   case OMPC_acq_rel:
16989   case OMPC_acquire:
16990   case OMPC_release:
16991   case OMPC_relaxed:
16992   case OMPC_depend:
16993   case OMPC_device:
16994   case OMPC_threads:
16995   case OMPC_simd:
16996   case OMPC_map:
16997   case OMPC_num_teams:
16998   case OMPC_thread_limit:
16999   case OMPC_priority:
17000   case OMPC_grainsize:
17001   case OMPC_nogroup:
17002   case OMPC_num_tasks:
17003   case OMPC_hint:
17004   case OMPC_dist_schedule:
17005   case OMPC_defaultmap:
17006   case OMPC_unknown:
17007   case OMPC_uniform:
17008   case OMPC_to:
17009   case OMPC_from:
17010   case OMPC_use_device_ptr:
17011   case OMPC_use_device_addr:
17012   case OMPC_is_device_ptr:
17013   case OMPC_has_device_addr:
17014   case OMPC_unified_address:
17015   case OMPC_unified_shared_memory:
17016   case OMPC_reverse_offload:
17017   case OMPC_dynamic_allocators:
17018   case OMPC_device_type:
17019   case OMPC_match:
17020   case OMPC_nontemporal:
17021   case OMPC_destroy:
17022   case OMPC_novariants:
17023   case OMPC_nocontext:
17024   case OMPC_detach:
17025   case OMPC_inclusive:
17026   case OMPC_exclusive:
17027   case OMPC_uses_allocators:
17028   case OMPC_affinity:
17029   case OMPC_when:
17030   case OMPC_message:
17031   default:
17032     llvm_unreachable("Clause is not allowed.");
17033   }
17034   return Res;
17035 }
17036 
17037 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=std::nullopt)17038 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
17039                         ArrayRef<unsigned> Exclude = std::nullopt) {
17040   SmallString<256> Buffer;
17041   llvm::raw_svector_ostream Out(Buffer);
17042   unsigned Skipped = Exclude.size();
17043   for (unsigned I = First; I < Last; ++I) {
17044     if (llvm::is_contained(Exclude, I)) {
17045       --Skipped;
17046       continue;
17047     }
17048     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
17049     if (I + Skipped + 2 == Last)
17050       Out << " or ";
17051     else if (I + Skipped + 1 != Last)
17052       Out << ", ";
17053   }
17054   return std::string(Out.str());
17055 }
17056 
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17057 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
17058                                           SourceLocation KindKwLoc,
17059                                           SourceLocation StartLoc,
17060                                           SourceLocation LParenLoc,
17061                                           SourceLocation EndLoc) {
17062   if (Kind == OMP_DEFAULT_unknown) {
17063     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17064         << getListOfPossibleValues(OMPC_default, /*First=*/0,
17065                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
17066         << getOpenMPClauseName(OMPC_default);
17067     return nullptr;
17068   }
17069 
17070   switch (Kind) {
17071   case OMP_DEFAULT_none:
17072     DSAStack->setDefaultDSANone(KindKwLoc);
17073     break;
17074   case OMP_DEFAULT_shared:
17075     DSAStack->setDefaultDSAShared(KindKwLoc);
17076     break;
17077   case OMP_DEFAULT_firstprivate:
17078     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17079     break;
17080   case OMP_DEFAULT_private:
17081     DSAStack->setDefaultDSAPrivate(KindKwLoc);
17082     break;
17083   default:
17084     llvm_unreachable("DSA unexpected in OpenMP default clause");
17085   }
17086 
17087   return new (Context)
17088       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17089 }
17090 
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17091 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
17092                                            SourceLocation KindKwLoc,
17093                                            SourceLocation StartLoc,
17094                                            SourceLocation LParenLoc,
17095                                            SourceLocation EndLoc) {
17096   if (Kind == OMP_PROC_BIND_unknown) {
17097     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17098         << getListOfPossibleValues(OMPC_proc_bind,
17099                                    /*First=*/unsigned(OMP_PROC_BIND_master),
17100                                    /*Last=*/
17101                                    unsigned(LangOpts.OpenMP > 50
17102                                                 ? OMP_PROC_BIND_primary
17103                                                 : OMP_PROC_BIND_spread) +
17104                                        1)
17105         << getOpenMPClauseName(OMPC_proc_bind);
17106     return nullptr;
17107   }
17108   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
17109     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17110         << getListOfPossibleValues(OMPC_proc_bind,
17111                                    /*First=*/unsigned(OMP_PROC_BIND_master),
17112                                    /*Last=*/
17113                                    unsigned(OMP_PROC_BIND_spread) + 1)
17114         << getOpenMPClauseName(OMPC_proc_bind);
17115   return new (Context)
17116       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17117 }
17118 
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17119 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
17120     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
17121     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
17122   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
17123     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17124         << getListOfPossibleValues(
17125                OMPC_atomic_default_mem_order, /*First=*/0,
17126                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
17127         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17128     return nullptr;
17129   }
17130   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
17131                                                       LParenLoc, EndLoc);
17132 }
17133 
ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17134 OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
17135                                      SourceLocation KindKwLoc,
17136                                      SourceLocation StartLoc,
17137                                      SourceLocation LParenLoc,
17138                                      SourceLocation EndLoc) {
17139   if (Kind == OMPC_AT_unknown) {
17140     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17141         << getListOfPossibleValues(OMPC_at, /*First=*/0,
17142                                    /*Last=*/OMPC_AT_unknown)
17143         << getOpenMPClauseName(OMPC_at);
17144     return nullptr;
17145   }
17146   return new (Context)
17147       OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17148 }
17149 
ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17150 OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
17151                                            SourceLocation KindKwLoc,
17152                                            SourceLocation StartLoc,
17153                                            SourceLocation LParenLoc,
17154                                            SourceLocation EndLoc) {
17155   if (Kind == OMPC_SEVERITY_unknown) {
17156     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17157         << getListOfPossibleValues(OMPC_severity, /*First=*/0,
17158                                    /*Last=*/OMPC_SEVERITY_unknown)
17159         << getOpenMPClauseName(OMPC_severity);
17160     return nullptr;
17161   }
17162   return new (Context)
17163       OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17164 }
17165 
ActOnOpenMPMessageClause(Expr * ME,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17166 OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
17167                                           SourceLocation LParenLoc,
17168                                           SourceLocation EndLoc) {
17169   assert(ME && "NULL expr in Message clause");
17170   if (!isa<StringLiteral>(ME)) {
17171     Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
17172         << getOpenMPClauseName(OMPC_message);
17173     return nullptr;
17174   }
17175   return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
17176 }
17177 
ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier,OpenMPOrderClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)17178 OMPClause *Sema::ActOnOpenMPOrderClause(
17179     OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
17180     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
17181     SourceLocation KindLoc, SourceLocation EndLoc) {
17182   if (Kind != OMPC_ORDER_concurrent ||
17183       (LangOpts.OpenMP < 51 && MLoc.isValid())) {
17184     // Kind should be concurrent,
17185     // Modifiers introduced in OpenMP 5.1
17186     static_assert(OMPC_ORDER_unknown > 0,
17187                   "OMPC_ORDER_unknown not greater than 0");
17188 
17189     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17190         << getListOfPossibleValues(OMPC_order,
17191                                    /*First=*/0,
17192                                    /*Last=*/OMPC_ORDER_unknown)
17193         << getOpenMPClauseName(OMPC_order);
17194     return nullptr;
17195   }
17196   if (LangOpts.OpenMP >= 51) {
17197     if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
17198       Diag(MLoc, diag::err_omp_unexpected_clause_value)
17199           << getListOfPossibleValues(OMPC_order,
17200                                      /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
17201                                      /*Last=*/OMPC_ORDER_MODIFIER_last)
17202           << getOpenMPClauseName(OMPC_order);
17203     } else {
17204       DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
17205       if (DSAStack->getCurScope()) {
17206         // mark the current scope with 'order' flag
17207         unsigned existingFlags = DSAStack->getCurScope()->getFlags();
17208         DSAStack->getCurScope()->setFlags(existingFlags |
17209                                           Scope::OpenMPOrderClauseScope);
17210       }
17211     }
17212   }
17213   return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
17214                                       EndLoc, Modifier, MLoc);
17215 }
17216 
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17217 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
17218                                          SourceLocation KindKwLoc,
17219                                          SourceLocation StartLoc,
17220                                          SourceLocation LParenLoc,
17221                                          SourceLocation EndLoc) {
17222   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
17223       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
17224     SmallVector<unsigned> Except = {
17225         OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17226         OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17227     if (LangOpts.OpenMP < 51)
17228       Except.push_back(OMPC_DEPEND_inoutset);
17229     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17230         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
17231                                    /*Last=*/OMPC_DEPEND_unknown, Except)
17232         << getOpenMPClauseName(OMPC_update);
17233     return nullptr;
17234   }
17235   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
17236                                  EndLoc);
17237 }
17238 
ActOnOpenMPSizesClause(ArrayRef<Expr * > SizeExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17239 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
17240                                         SourceLocation StartLoc,
17241                                         SourceLocation LParenLoc,
17242                                         SourceLocation EndLoc) {
17243   for (Expr *SizeExpr : SizeExprs) {
17244     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
17245         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
17246     if (!NumForLoopsResult.isUsable())
17247       return nullptr;
17248   }
17249 
17250   DSAStack->setAssociatedLoops(SizeExprs.size());
17251   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17252                                 SizeExprs);
17253 }
17254 
ActOnOpenMPFullClause(SourceLocation StartLoc,SourceLocation EndLoc)17255 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
17256                                        SourceLocation EndLoc) {
17257   return OMPFullClause::Create(Context, StartLoc, EndLoc);
17258 }
17259 
ActOnOpenMPPartialClause(Expr * FactorExpr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17260 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
17261                                           SourceLocation StartLoc,
17262                                           SourceLocation LParenLoc,
17263                                           SourceLocation EndLoc) {
17264   if (FactorExpr) {
17265     // If an argument is specified, it must be a constant (or an unevaluated
17266     // template expression).
17267     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
17268         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
17269     if (FactorResult.isInvalid())
17270       return nullptr;
17271     FactorExpr = FactorResult.get();
17272   }
17273 
17274   return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17275                                   FactorExpr);
17276 }
17277 
ActOnOpenMPAlignClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17278 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
17279                                         SourceLocation LParenLoc,
17280                                         SourceLocation EndLoc) {
17281   ExprResult AlignVal;
17282   AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
17283   if (AlignVal.isInvalid())
17284     return nullptr;
17285   return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
17286                                 EndLoc);
17287 }
17288 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)17289 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
17290     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
17291     SourceLocation StartLoc, SourceLocation LParenLoc,
17292     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
17293     SourceLocation EndLoc) {
17294   OMPClause *Res = nullptr;
17295   switch (Kind) {
17296   case OMPC_schedule:
17297     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17298     assert(Argument.size() == NumberOfElements &&
17299            ArgumentLoc.size() == NumberOfElements);
17300     Res = ActOnOpenMPScheduleClause(
17301         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
17302         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
17303         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
17304         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17305         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17306     break;
17307   case OMPC_if:
17308     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17309     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
17310                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17311                               DelimLoc, EndLoc);
17312     break;
17313   case OMPC_dist_schedule:
17314     Res = ActOnOpenMPDistScheduleClause(
17315         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
17316         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17317     break;
17318   case OMPC_defaultmap:
17319     enum { Modifier, DefaultmapKind };
17320     Res = ActOnOpenMPDefaultmapClause(
17321         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
17322         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
17323         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17324         EndLoc);
17325     break;
17326   case OMPC_order:
17327     enum { OrderModifier, OrderKind };
17328     Res = ActOnOpenMPOrderClause(
17329         static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
17330         static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
17331         LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17332     break;
17333   case OMPC_device:
17334     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17335     Res = ActOnOpenMPDeviceClause(
17336         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
17337         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17338     break;
17339   case OMPC_grainsize:
17340     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17341            "Modifier for grainsize clause and its location are expected.");
17342     Res = ActOnOpenMPGrainsizeClause(
17343         static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
17344         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17345     break;
17346   case OMPC_num_tasks:
17347     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17348            "Modifier for num_tasks clause and its location are expected.");
17349     Res = ActOnOpenMPNumTasksClause(
17350         static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
17351         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17352     break;
17353   case OMPC_final:
17354   case OMPC_num_threads:
17355   case OMPC_safelen:
17356   case OMPC_simdlen:
17357   case OMPC_sizes:
17358   case OMPC_allocator:
17359   case OMPC_collapse:
17360   case OMPC_default:
17361   case OMPC_proc_bind:
17362   case OMPC_private:
17363   case OMPC_firstprivate:
17364   case OMPC_lastprivate:
17365   case OMPC_shared:
17366   case OMPC_reduction:
17367   case OMPC_task_reduction:
17368   case OMPC_in_reduction:
17369   case OMPC_linear:
17370   case OMPC_aligned:
17371   case OMPC_copyin:
17372   case OMPC_copyprivate:
17373   case OMPC_ordered:
17374   case OMPC_nowait:
17375   case OMPC_untied:
17376   case OMPC_mergeable:
17377   case OMPC_threadprivate:
17378   case OMPC_allocate:
17379   case OMPC_flush:
17380   case OMPC_depobj:
17381   case OMPC_read:
17382   case OMPC_write:
17383   case OMPC_update:
17384   case OMPC_capture:
17385   case OMPC_compare:
17386   case OMPC_seq_cst:
17387   case OMPC_acq_rel:
17388   case OMPC_acquire:
17389   case OMPC_release:
17390   case OMPC_relaxed:
17391   case OMPC_depend:
17392   case OMPC_threads:
17393   case OMPC_simd:
17394   case OMPC_map:
17395   case OMPC_num_teams:
17396   case OMPC_thread_limit:
17397   case OMPC_priority:
17398   case OMPC_nogroup:
17399   case OMPC_hint:
17400   case OMPC_unknown:
17401   case OMPC_uniform:
17402   case OMPC_to:
17403   case OMPC_from:
17404   case OMPC_use_device_ptr:
17405   case OMPC_use_device_addr:
17406   case OMPC_is_device_ptr:
17407   case OMPC_has_device_addr:
17408   case OMPC_unified_address:
17409   case OMPC_unified_shared_memory:
17410   case OMPC_reverse_offload:
17411   case OMPC_dynamic_allocators:
17412   case OMPC_atomic_default_mem_order:
17413   case OMPC_device_type:
17414   case OMPC_match:
17415   case OMPC_nontemporal:
17416   case OMPC_at:
17417   case OMPC_severity:
17418   case OMPC_message:
17419   case OMPC_destroy:
17420   case OMPC_novariants:
17421   case OMPC_nocontext:
17422   case OMPC_detach:
17423   case OMPC_inclusive:
17424   case OMPC_exclusive:
17425   case OMPC_uses_allocators:
17426   case OMPC_affinity:
17427   case OMPC_when:
17428   case OMPC_bind:
17429   default:
17430     llvm_unreachable("Clause is not allowed.");
17431   }
17432   return Res;
17433 }
17434 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)17435 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
17436                                    OpenMPScheduleClauseModifier M2,
17437                                    SourceLocation M1Loc, SourceLocation M2Loc) {
17438   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
17439     SmallVector<unsigned, 2> Excluded;
17440     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
17441       Excluded.push_back(M2);
17442     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17443       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17444     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17445       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17446     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17447         << getListOfPossibleValues(OMPC_schedule,
17448                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17449                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17450                                    Excluded)
17451         << getOpenMPClauseName(OMPC_schedule);
17452     return true;
17453   }
17454   return false;
17455 }
17456 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)17457 OMPClause *Sema::ActOnOpenMPScheduleClause(
17458     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
17459     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17460     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17461     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17462   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17463       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17464     return nullptr;
17465   // OpenMP, 2.7.1, Loop Construct, Restrictions
17466   // Either the monotonic modifier or the nonmonotonic modifier can be specified
17467   // but not both.
17468   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
17469       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17470        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17471       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17472        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17473     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17474         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17475         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17476     return nullptr;
17477   }
17478   if (Kind == OMPC_SCHEDULE_unknown) {
17479     std::string Values;
17480     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
17481       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17482       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17483                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17484                                        Exclude);
17485     } else {
17486       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17487                                        /*Last=*/OMPC_SCHEDULE_unknown);
17488     }
17489     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17490         << Values << getOpenMPClauseName(OMPC_schedule);
17491     return nullptr;
17492   }
17493   // OpenMP, 2.7.1, Loop Construct, Restrictions
17494   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17495   // schedule(guided).
17496   // OpenMP 5.0 does not have this restriction.
17497   if (LangOpts.OpenMP < 50 &&
17498       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17499        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17500       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17501     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17502          diag::err_omp_schedule_nonmonotonic_static);
17503     return nullptr;
17504   }
17505   Expr *ValExpr = ChunkSize;
17506   Stmt *HelperValStmt = nullptr;
17507   if (ChunkSize) {
17508     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17509         !ChunkSize->isInstantiationDependent() &&
17510         !ChunkSize->containsUnexpandedParameterPack()) {
17511       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17512       ExprResult Val =
17513           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17514       if (Val.isInvalid())
17515         return nullptr;
17516 
17517       ValExpr = Val.get();
17518 
17519       // OpenMP [2.7.1, Restrictions]
17520       //  chunk_size must be a loop invariant integer expression with a positive
17521       //  value.
17522       if (std::optional<llvm::APSInt> Result =
17523               ValExpr->getIntegerConstantExpr(Context)) {
17524         if (Result->isSigned() && !Result->isStrictlyPositive()) {
17525           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17526               << "schedule" << 1 << ChunkSize->getSourceRange();
17527           return nullptr;
17528         }
17529       } else if (getOpenMPCaptureRegionForClause(
17530                      DSAStack->getCurrentDirective(), OMPC_schedule,
17531                      LangOpts.OpenMP) != OMPD_unknown &&
17532                  !CurContext->isDependentContext()) {
17533         ValExpr = MakeFullExpr(ValExpr).get();
17534         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17535         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17536         HelperValStmt = buildPreInits(Context, Captures);
17537       }
17538     }
17539   }
17540 
17541   return new (Context)
17542       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17543                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17544 }
17545 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)17546 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
17547                                    SourceLocation StartLoc,
17548                                    SourceLocation EndLoc) {
17549   OMPClause *Res = nullptr;
17550   switch (Kind) {
17551   case OMPC_ordered:
17552     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17553     break;
17554   case OMPC_nowait:
17555     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17556     break;
17557   case OMPC_untied:
17558     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17559     break;
17560   case OMPC_mergeable:
17561     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17562     break;
17563   case OMPC_read:
17564     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17565     break;
17566   case OMPC_write:
17567     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17568     break;
17569   case OMPC_update:
17570     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17571     break;
17572   case OMPC_capture:
17573     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17574     break;
17575   case OMPC_compare:
17576     Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17577     break;
17578   case OMPC_fail:
17579     Res = ActOnOpenMPFailClause(StartLoc, EndLoc);
17580     break;
17581   case OMPC_seq_cst:
17582     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17583     break;
17584   case OMPC_acq_rel:
17585     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17586     break;
17587   case OMPC_acquire:
17588     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17589     break;
17590   case OMPC_release:
17591     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17592     break;
17593   case OMPC_relaxed:
17594     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17595     break;
17596   case OMPC_threads:
17597     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17598     break;
17599   case OMPC_simd:
17600     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17601     break;
17602   case OMPC_nogroup:
17603     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17604     break;
17605   case OMPC_unified_address:
17606     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17607     break;
17608   case OMPC_unified_shared_memory:
17609     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17610     break;
17611   case OMPC_reverse_offload:
17612     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17613     break;
17614   case OMPC_dynamic_allocators:
17615     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17616     break;
17617   case OMPC_destroy:
17618     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17619                                    /*LParenLoc=*/SourceLocation(),
17620                                    /*VarLoc=*/SourceLocation(), EndLoc);
17621     break;
17622   case OMPC_full:
17623     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17624     break;
17625   case OMPC_partial:
17626     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17627     break;
17628   case OMPC_ompx_bare:
17629     Res = ActOnOpenMPXBareClause(StartLoc, EndLoc);
17630     break;
17631   case OMPC_if:
17632   case OMPC_final:
17633   case OMPC_num_threads:
17634   case OMPC_safelen:
17635   case OMPC_simdlen:
17636   case OMPC_sizes:
17637   case OMPC_allocator:
17638   case OMPC_collapse:
17639   case OMPC_schedule:
17640   case OMPC_private:
17641   case OMPC_firstprivate:
17642   case OMPC_lastprivate:
17643   case OMPC_shared:
17644   case OMPC_reduction:
17645   case OMPC_task_reduction:
17646   case OMPC_in_reduction:
17647   case OMPC_linear:
17648   case OMPC_aligned:
17649   case OMPC_copyin:
17650   case OMPC_copyprivate:
17651   case OMPC_default:
17652   case OMPC_proc_bind:
17653   case OMPC_threadprivate:
17654   case OMPC_allocate:
17655   case OMPC_flush:
17656   case OMPC_depobj:
17657   case OMPC_depend:
17658   case OMPC_device:
17659   case OMPC_map:
17660   case OMPC_num_teams:
17661   case OMPC_thread_limit:
17662   case OMPC_priority:
17663   case OMPC_grainsize:
17664   case OMPC_num_tasks:
17665   case OMPC_hint:
17666   case OMPC_dist_schedule:
17667   case OMPC_defaultmap:
17668   case OMPC_unknown:
17669   case OMPC_uniform:
17670   case OMPC_to:
17671   case OMPC_from:
17672   case OMPC_use_device_ptr:
17673   case OMPC_use_device_addr:
17674   case OMPC_is_device_ptr:
17675   case OMPC_has_device_addr:
17676   case OMPC_atomic_default_mem_order:
17677   case OMPC_device_type:
17678   case OMPC_match:
17679   case OMPC_nontemporal:
17680   case OMPC_order:
17681   case OMPC_at:
17682   case OMPC_severity:
17683   case OMPC_message:
17684   case OMPC_novariants:
17685   case OMPC_nocontext:
17686   case OMPC_detach:
17687   case OMPC_inclusive:
17688   case OMPC_exclusive:
17689   case OMPC_uses_allocators:
17690   case OMPC_affinity:
17691   case OMPC_when:
17692   case OMPC_ompx_dyn_cgroup_mem:
17693   default:
17694     llvm_unreachable("Clause is not allowed.");
17695   }
17696   return Res;
17697 }
17698 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)17699 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17700                                          SourceLocation EndLoc) {
17701   DSAStack->setNowaitRegion();
17702   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17703 }
17704 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)17705 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17706                                          SourceLocation EndLoc) {
17707   DSAStack->setUntiedRegion();
17708   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17709 }
17710 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)17711 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17712                                             SourceLocation EndLoc) {
17713   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17714 }
17715 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)17716 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17717                                        SourceLocation EndLoc) {
17718   return new (Context) OMPReadClause(StartLoc, EndLoc);
17719 }
17720 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)17721 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17722                                         SourceLocation EndLoc) {
17723   return new (Context) OMPWriteClause(StartLoc, EndLoc);
17724 }
17725 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)17726 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17727                                          SourceLocation EndLoc) {
17728   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17729 }
17730 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)17731 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17732                                           SourceLocation EndLoc) {
17733   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17734 }
17735 
ActOnOpenMPCompareClause(SourceLocation StartLoc,SourceLocation EndLoc)17736 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17737                                           SourceLocation EndLoc) {
17738   return new (Context) OMPCompareClause(StartLoc, EndLoc);
17739 }
17740 
ActOnOpenMPFailClause(SourceLocation StartLoc,SourceLocation EndLoc)17741 OMPClause *Sema::ActOnOpenMPFailClause(SourceLocation StartLoc,
17742                                        SourceLocation EndLoc) {
17743   return new (Context) OMPFailClause(StartLoc, EndLoc);
17744 }
17745 
ActOnOpenMPFailClause(OpenMPClauseKind Parameter,SourceLocation KindLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17746 OMPClause *Sema::ActOnOpenMPFailClause(
17747       OpenMPClauseKind Parameter, SourceLocation KindLoc,
17748       SourceLocation StartLoc, SourceLocation LParenLoc,
17749       SourceLocation EndLoc) {
17750 
17751   if (!checkFailClauseParameter(Parameter)) {
17752     Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
17753     return nullptr;
17754   }
17755   return new (Context)
17756       OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc);
17757 }
17758 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)17759 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17760                                          SourceLocation EndLoc) {
17761   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17762 }
17763 
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)17764 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17765                                          SourceLocation EndLoc) {
17766   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17767 }
17768 
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)17769 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17770                                           SourceLocation EndLoc) {
17771   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17772 }
17773 
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)17774 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17775                                           SourceLocation EndLoc) {
17776   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17777 }
17778 
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)17779 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17780                                           SourceLocation EndLoc) {
17781   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17782 }
17783 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)17784 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17785                                           SourceLocation EndLoc) {
17786   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17787 }
17788 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)17789 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17790                                        SourceLocation EndLoc) {
17791   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17792 }
17793 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)17794 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17795                                           SourceLocation EndLoc) {
17796   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17797 }
17798 
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)17799 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17800                                                  SourceLocation EndLoc) {
17801   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17802 }
17803 
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)17804 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17805                                                       SourceLocation EndLoc) {
17806   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17807 }
17808 
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)17809 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17810                                                  SourceLocation EndLoc) {
17811   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17812 }
17813 
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)17814 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17815                                                     SourceLocation EndLoc) {
17816   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17817 }
17818 
ActOnOpenMPInteropDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)17819 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17820                                              SourceLocation StartLoc,
17821                                              SourceLocation EndLoc) {
17822 
17823   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17824   // At least one action-clause must appear on a directive.
17825   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17826     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17827     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17828         << Expected << getOpenMPDirectiveName(OMPD_interop);
17829     return StmtError();
17830   }
17831 
17832   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17833   // A depend clause can only appear on the directive if a targetsync
17834   // interop-type is present or the interop-var was initialized with
17835   // the targetsync interop-type.
17836 
17837   // If there is any 'init' clause diagnose if there is no 'init' clause with
17838   // interop-type of 'targetsync'. Cases involving other directives cannot be
17839   // diagnosed.
17840   const OMPDependClause *DependClause = nullptr;
17841   bool HasInitClause = false;
17842   bool IsTargetSync = false;
17843   for (const OMPClause *C : Clauses) {
17844     if (IsTargetSync)
17845       break;
17846     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17847       HasInitClause = true;
17848       if (InitClause->getIsTargetSync())
17849         IsTargetSync = true;
17850     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17851       DependClause = DC;
17852     }
17853   }
17854   if (DependClause && HasInitClause && !IsTargetSync) {
17855     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17856     return StmtError();
17857   }
17858 
17859   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17860   // Each interop-var may be specified for at most one action-clause of each
17861   // interop construct.
17862   llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
17863   for (OMPClause *C : Clauses) {
17864     OpenMPClauseKind ClauseKind = C->getClauseKind();
17865     std::pair<ValueDecl *, bool> DeclResult;
17866     SourceLocation ELoc;
17867     SourceRange ERange;
17868 
17869     if (ClauseKind == OMPC_init) {
17870       auto *E = cast<OMPInitClause>(C)->getInteropVar();
17871       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17872     } else if (ClauseKind == OMPC_use) {
17873       auto *E = cast<OMPUseClause>(C)->getInteropVar();
17874       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17875     } else if (ClauseKind == OMPC_destroy) {
17876       auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17877       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17878     }
17879 
17880     if (DeclResult.first) {
17881       if (!InteropVars.insert(DeclResult.first).second) {
17882         Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17883             << DeclResult.first;
17884         return StmtError();
17885       }
17886     }
17887   }
17888 
17889   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17890 }
17891 
isValidInteropVariable(Sema & SemaRef,Expr * InteropVarExpr,SourceLocation VarLoc,OpenMPClauseKind Kind)17892 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17893                                    SourceLocation VarLoc,
17894                                    OpenMPClauseKind Kind) {
17895   SourceLocation ELoc;
17896   SourceRange ERange;
17897   Expr *RefExpr = InteropVarExpr;
17898   auto Res =
17899       getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17900                      /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17901 
17902   if (Res.second) {
17903     // It will be analyzed later.
17904     return true;
17905   }
17906 
17907   if (!Res.first)
17908     return false;
17909 
17910   // Interop variable should be of type omp_interop_t.
17911   bool HasError = false;
17912   QualType InteropType;
17913   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17914                       VarLoc, Sema::LookupOrdinaryName);
17915   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17916     NamedDecl *ND = Result.getFoundDecl();
17917     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17918       InteropType = QualType(TD->getTypeForDecl(), 0);
17919     } else {
17920       HasError = true;
17921     }
17922   } else {
17923     HasError = true;
17924   }
17925 
17926   if (HasError) {
17927     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17928         << "omp_interop_t";
17929     return false;
17930   }
17931 
17932   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17933   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17934     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17935     return false;
17936   }
17937 
17938   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17939   // The interop-var passed to init or destroy must be non-const.
17940   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17941       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17942     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17943         << /*non-const*/ 1;
17944     return false;
17945   }
17946   return true;
17947 }
17948 
17949 OMPClause *
ActOnOpenMPInitClause(Expr * InteropVar,OMPInteropInfo & InteropInfo,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)17950 Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
17951                             SourceLocation StartLoc, SourceLocation LParenLoc,
17952                             SourceLocation VarLoc, SourceLocation EndLoc) {
17953 
17954   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17955     return nullptr;
17956 
17957   // Check prefer_type values.  These foreign-runtime-id values are either
17958   // string literals or constant integral expressions.
17959   for (const Expr *E : InteropInfo.PreferTypes) {
17960     if (E->isValueDependent() || E->isTypeDependent() ||
17961         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
17962       continue;
17963     if (E->isIntegerConstantExpr(Context))
17964       continue;
17965     if (isa<StringLiteral>(E))
17966       continue;
17967     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17968     return nullptr;
17969   }
17970 
17971   return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17972                                LParenLoc, VarLoc, EndLoc);
17973 }
17974 
ActOnOpenMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)17975 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17976                                       SourceLocation LParenLoc,
17977                                       SourceLocation VarLoc,
17978                                       SourceLocation EndLoc) {
17979 
17980   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17981     return nullptr;
17982 
17983   return new (Context)
17984       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17985 }
17986 
ActOnOpenMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)17987 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17988                                           SourceLocation StartLoc,
17989                                           SourceLocation LParenLoc,
17990                                           SourceLocation VarLoc,
17991                                           SourceLocation EndLoc) {
17992   if (!InteropVar && LangOpts.OpenMP >= 52 &&
17993       DSAStack->getCurrentDirective() == OMPD_depobj) {
17994     Diag(StartLoc, diag::err_omp_expected_clause_argument)
17995         << getOpenMPClauseName(OMPC_destroy)
17996         << getOpenMPDirectiveName(OMPD_depobj);
17997     return nullptr;
17998   }
17999   if (InteropVar &&
18000       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
18001     return nullptr;
18002 
18003   return new (Context)
18004       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
18005 }
18006 
ActOnOpenMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18007 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
18008                                              SourceLocation StartLoc,
18009                                              SourceLocation LParenLoc,
18010                                              SourceLocation EndLoc) {
18011   Expr *ValExpr = Condition;
18012   Stmt *HelperValStmt = nullptr;
18013   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18014   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
18015       !Condition->isInstantiationDependent() &&
18016       !Condition->containsUnexpandedParameterPack()) {
18017     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
18018     if (Val.isInvalid())
18019       return nullptr;
18020 
18021     ValExpr = MakeFullExpr(Val.get()).get();
18022 
18023     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18024     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
18025                                                     LangOpts.OpenMP);
18026     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18027       ValExpr = MakeFullExpr(ValExpr).get();
18028       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18029       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18030       HelperValStmt = buildPreInits(Context, Captures);
18031     }
18032   }
18033 
18034   return new (Context) OMPNovariantsClause(
18035       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18036 }
18037 
ActOnOpenMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18038 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
18039                                             SourceLocation StartLoc,
18040                                             SourceLocation LParenLoc,
18041                                             SourceLocation EndLoc) {
18042   Expr *ValExpr = Condition;
18043   Stmt *HelperValStmt = nullptr;
18044   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18045   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
18046       !Condition->isInstantiationDependent() &&
18047       !Condition->containsUnexpandedParameterPack()) {
18048     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
18049     if (Val.isInvalid())
18050       return nullptr;
18051 
18052     ValExpr = MakeFullExpr(Val.get()).get();
18053 
18054     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18055     CaptureRegion =
18056         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
18057     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18058       ValExpr = MakeFullExpr(ValExpr).get();
18059       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18060       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18061       HelperValStmt = buildPreInits(Context, Captures);
18062     }
18063   }
18064 
18065   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
18066                                           StartLoc, LParenLoc, EndLoc);
18067 }
18068 
ActOnOpenMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18069 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
18070                                          SourceLocation StartLoc,
18071                                          SourceLocation LParenLoc,
18072                                          SourceLocation EndLoc) {
18073   Expr *ValExpr = ThreadID;
18074   Stmt *HelperValStmt = nullptr;
18075 
18076   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18077   OpenMPDirectiveKind CaptureRegion =
18078       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
18079   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18080     ValExpr = MakeFullExpr(ValExpr).get();
18081     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18082     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18083     HelperValStmt = buildPreInits(Context, Captures);
18084   }
18085 
18086   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
18087                                        StartLoc, LParenLoc, EndLoc);
18088 }
18089 
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,OpenMPVarListDataTy & Data)18090 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
18091                                           ArrayRef<Expr *> VarList,
18092                                           const OMPVarListLocTy &Locs,
18093                                           OpenMPVarListDataTy &Data) {
18094   SourceLocation StartLoc = Locs.StartLoc;
18095   SourceLocation LParenLoc = Locs.LParenLoc;
18096   SourceLocation EndLoc = Locs.EndLoc;
18097   OMPClause *Res = nullptr;
18098   int ExtraModifier = Data.ExtraModifier;
18099   SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
18100   SourceLocation ColonLoc = Data.ColonLoc;
18101   switch (Kind) {
18102   case OMPC_private:
18103     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18104     break;
18105   case OMPC_firstprivate:
18106     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18107     break;
18108   case OMPC_lastprivate:
18109     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
18110            "Unexpected lastprivate modifier.");
18111     Res = ActOnOpenMPLastprivateClause(
18112         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
18113         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18114     break;
18115   case OMPC_shared:
18116     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
18117     break;
18118   case OMPC_reduction:
18119     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
18120            "Unexpected lastprivate modifier.");
18121     Res = ActOnOpenMPReductionClause(
18122         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
18123         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18124         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18125     break;
18126   case OMPC_task_reduction:
18127     Res = ActOnOpenMPTaskReductionClause(
18128         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18129         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18130     break;
18131   case OMPC_in_reduction:
18132     Res = ActOnOpenMPInReductionClause(
18133         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18134         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18135     break;
18136   case OMPC_linear:
18137     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
18138            "Unexpected linear modifier.");
18139     Res = ActOnOpenMPLinearClause(
18140         VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
18141         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
18142         ColonLoc, Data.StepModifierLoc, EndLoc);
18143     break;
18144   case OMPC_aligned:
18145     Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
18146                                    LParenLoc, ColonLoc, EndLoc);
18147     break;
18148   case OMPC_copyin:
18149     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
18150     break;
18151   case OMPC_copyprivate:
18152     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18153     break;
18154   case OMPC_flush:
18155     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
18156     break;
18157   case OMPC_depend:
18158     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
18159            "Unexpected depend modifier.");
18160     Res = ActOnOpenMPDependClause(
18161         {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
18162          ColonLoc, Data.OmpAllMemoryLoc},
18163         Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18164     break;
18165   case OMPC_map:
18166     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
18167            "Unexpected map modifier.");
18168     Res = ActOnOpenMPMapClause(
18169         Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
18170         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
18171         static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
18172         ExtraModifierLoc, ColonLoc, VarList, Locs);
18173     break;
18174   case OMPC_to:
18175     Res =
18176         ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18177                             Data.ReductionOrMapperIdScopeSpec,
18178                             Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18179     break;
18180   case OMPC_from:
18181     Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18182                                 Data.ReductionOrMapperIdScopeSpec,
18183                                 Data.ReductionOrMapperId, ColonLoc, VarList,
18184                                 Locs);
18185     break;
18186   case OMPC_use_device_ptr:
18187     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
18188     break;
18189   case OMPC_use_device_addr:
18190     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
18191     break;
18192   case OMPC_is_device_ptr:
18193     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
18194     break;
18195   case OMPC_has_device_addr:
18196     Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
18197     break;
18198   case OMPC_allocate:
18199     Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
18200                                     LParenLoc, ColonLoc, EndLoc);
18201     break;
18202   case OMPC_nontemporal:
18203     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
18204     break;
18205   case OMPC_inclusive:
18206     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18207     break;
18208   case OMPC_exclusive:
18209     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18210     break;
18211   case OMPC_affinity:
18212     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
18213                                     Data.DepModOrTailExpr, VarList);
18214     break;
18215   case OMPC_doacross:
18216     Res = ActOnOpenMPDoacrossClause(
18217         static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
18218         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18219     break;
18220   case OMPC_if:
18221   case OMPC_depobj:
18222   case OMPC_final:
18223   case OMPC_num_threads:
18224   case OMPC_safelen:
18225   case OMPC_simdlen:
18226   case OMPC_sizes:
18227   case OMPC_allocator:
18228   case OMPC_collapse:
18229   case OMPC_default:
18230   case OMPC_proc_bind:
18231   case OMPC_schedule:
18232   case OMPC_ordered:
18233   case OMPC_nowait:
18234   case OMPC_untied:
18235   case OMPC_mergeable:
18236   case OMPC_threadprivate:
18237   case OMPC_read:
18238   case OMPC_write:
18239   case OMPC_update:
18240   case OMPC_capture:
18241   case OMPC_compare:
18242   case OMPC_seq_cst:
18243   case OMPC_acq_rel:
18244   case OMPC_acquire:
18245   case OMPC_release:
18246   case OMPC_relaxed:
18247   case OMPC_device:
18248   case OMPC_threads:
18249   case OMPC_simd:
18250   case OMPC_num_teams:
18251   case OMPC_thread_limit:
18252   case OMPC_priority:
18253   case OMPC_grainsize:
18254   case OMPC_nogroup:
18255   case OMPC_num_tasks:
18256   case OMPC_hint:
18257   case OMPC_dist_schedule:
18258   case OMPC_defaultmap:
18259   case OMPC_unknown:
18260   case OMPC_uniform:
18261   case OMPC_unified_address:
18262   case OMPC_unified_shared_memory:
18263   case OMPC_reverse_offload:
18264   case OMPC_dynamic_allocators:
18265   case OMPC_atomic_default_mem_order:
18266   case OMPC_device_type:
18267   case OMPC_match:
18268   case OMPC_order:
18269   case OMPC_at:
18270   case OMPC_severity:
18271   case OMPC_message:
18272   case OMPC_destroy:
18273   case OMPC_novariants:
18274   case OMPC_nocontext:
18275   case OMPC_detach:
18276   case OMPC_uses_allocators:
18277   case OMPC_when:
18278   case OMPC_bind:
18279   default:
18280     llvm_unreachable("Clause is not allowed.");
18281   }
18282   return Res;
18283 }
18284 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)18285 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
18286                                        ExprObjectKind OK, SourceLocation Loc) {
18287   ExprResult Res = BuildDeclRefExpr(
18288       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
18289   if (!Res.isUsable())
18290     return ExprError();
18291   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
18292     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
18293     if (!Res.isUsable())
18294       return ExprError();
18295   }
18296   if (VK != VK_LValue && Res.get()->isGLValue()) {
18297     Res = DefaultLvalueConversion(Res.get());
18298     if (!Res.isUsable())
18299       return ExprError();
18300   }
18301   return Res;
18302 }
18303 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18304 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
18305                                           SourceLocation StartLoc,
18306                                           SourceLocation LParenLoc,
18307                                           SourceLocation EndLoc) {
18308   SmallVector<Expr *, 8> Vars;
18309   SmallVector<Expr *, 8> PrivateCopies;
18310   bool IsImplicitClause =
18311       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18312   for (Expr *RefExpr : VarList) {
18313     assert(RefExpr && "NULL expr in OpenMP private clause.");
18314     SourceLocation ELoc;
18315     SourceRange ERange;
18316     Expr *SimpleRefExpr = RefExpr;
18317     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18318     if (Res.second) {
18319       // It will be analyzed later.
18320       Vars.push_back(RefExpr);
18321       PrivateCopies.push_back(nullptr);
18322     }
18323     ValueDecl *D = Res.first;
18324     if (!D)
18325       continue;
18326 
18327     QualType Type = D->getType();
18328     auto *VD = dyn_cast<VarDecl>(D);
18329 
18330     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18331     //  A variable that appears in a private clause must not have an incomplete
18332     //  type or a reference type.
18333     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
18334       continue;
18335     Type = Type.getNonReferenceType();
18336 
18337     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18338     // A variable that is privatized must not have a const-qualified type
18339     // unless it is of class type with a mutable member. This restriction does
18340     // not apply to the firstprivate clause.
18341     //
18342     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
18343     // A variable that appears in a private clause must not have a
18344     // const-qualified type unless it is of class type with a mutable member.
18345     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
18346       continue;
18347 
18348     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18349     // in a Construct]
18350     //  Variables with the predetermined data-sharing attributes may not be
18351     //  listed in data-sharing attributes clauses, except for the cases
18352     //  listed below. For these exceptions only, listing a predetermined
18353     //  variable in a data-sharing attribute clause is allowed and overrides
18354     //  the variable's predetermined data-sharing attributes.
18355     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18356     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18357       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18358                                           << getOpenMPClauseName(OMPC_private);
18359       reportOriginalDsa(*this, DSAStack, D, DVar);
18360       continue;
18361     }
18362 
18363     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18364     // Variably modified types are not supported for tasks.
18365     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18366         isOpenMPTaskingDirective(CurrDir)) {
18367       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18368           << getOpenMPClauseName(OMPC_private) << Type
18369           << getOpenMPDirectiveName(CurrDir);
18370       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18371                                VarDecl::DeclarationOnly;
18372       Diag(D->getLocation(),
18373            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18374           << D;
18375       continue;
18376     }
18377 
18378     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18379     // A list item cannot appear in both a map clause and a data-sharing
18380     // attribute clause on the same construct
18381     //
18382     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18383     // A list item cannot appear in both a map clause and a data-sharing
18384     // attribute clause on the same construct unless the construct is a
18385     // combined construct.
18386     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
18387         CurrDir == OMPD_target) {
18388       OpenMPClauseKind ConflictKind;
18389       if (DSAStack->checkMappableExprComponentListsForDecl(
18390               VD, /*CurrentRegionOnly=*/true,
18391               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
18392                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
18393                 ConflictKind = WhereFoundClauseKind;
18394                 return true;
18395               })) {
18396         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18397             << getOpenMPClauseName(OMPC_private)
18398             << getOpenMPClauseName(ConflictKind)
18399             << getOpenMPDirectiveName(CurrDir);
18400         reportOriginalDsa(*this, DSAStack, D, DVar);
18401         continue;
18402       }
18403     }
18404 
18405     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
18406     //  A variable of class type (or array thereof) that appears in a private
18407     //  clause requires an accessible, unambiguous default constructor for the
18408     //  class type.
18409     // Generate helper private variable and initialize it with the default
18410     // value. The address of the original variable is replaced by the address of
18411     // the new private variable in CodeGen. This new variable is not added to
18412     // IdResolver, so the code in the OpenMP region uses original variable for
18413     // proper diagnostics.
18414     Type = Type.getUnqualifiedType();
18415     VarDecl *VDPrivate =
18416         buildVarDecl(*this, ELoc, Type, D->getName(),
18417                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18418                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18419     ActOnUninitializedDecl(VDPrivate);
18420     if (VDPrivate->isInvalidDecl())
18421       continue;
18422     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18423         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18424 
18425     DeclRefExpr *Ref = nullptr;
18426     if (!VD && !CurContext->isDependentContext()) {
18427       auto *FD = dyn_cast<FieldDecl>(D);
18428       VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18429       if (VD)
18430         Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18431                                RefExpr->getExprLoc());
18432       else
18433         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18434     }
18435     if (!IsImplicitClause)
18436       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18437     Vars.push_back((VD || CurContext->isDependentContext())
18438                        ? RefExpr->IgnoreParens()
18439                        : Ref);
18440     PrivateCopies.push_back(VDPrivateRefExpr);
18441   }
18442 
18443   if (Vars.empty())
18444     return nullptr;
18445 
18446   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18447                                   PrivateCopies);
18448 }
18449 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18450 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
18451                                                SourceLocation StartLoc,
18452                                                SourceLocation LParenLoc,
18453                                                SourceLocation EndLoc) {
18454   SmallVector<Expr *, 8> Vars;
18455   SmallVector<Expr *, 8> PrivateCopies;
18456   SmallVector<Expr *, 8> Inits;
18457   SmallVector<Decl *, 4> ExprCaptures;
18458   bool IsImplicitClause =
18459       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18460   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
18461 
18462   for (Expr *RefExpr : VarList) {
18463     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
18464     SourceLocation ELoc;
18465     SourceRange ERange;
18466     Expr *SimpleRefExpr = RefExpr;
18467     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18468     if (Res.second) {
18469       // It will be analyzed later.
18470       Vars.push_back(RefExpr);
18471       PrivateCopies.push_back(nullptr);
18472       Inits.push_back(nullptr);
18473     }
18474     ValueDecl *D = Res.first;
18475     if (!D)
18476       continue;
18477 
18478     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18479     QualType Type = D->getType();
18480     auto *VD = dyn_cast<VarDecl>(D);
18481 
18482     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18483     //  A variable that appears in a private clause must not have an incomplete
18484     //  type or a reference type.
18485     if (RequireCompleteType(ELoc, Type,
18486                             diag::err_omp_firstprivate_incomplete_type))
18487       continue;
18488     Type = Type.getNonReferenceType();
18489 
18490     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18491     //  A variable of class type (or array thereof) that appears in a private
18492     //  clause requires an accessible, unambiguous copy constructor for the
18493     //  class type.
18494     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18495 
18496     // If an implicit firstprivate variable found it was checked already.
18497     DSAStackTy::DSAVarData TopDVar;
18498     if (!IsImplicitClause) {
18499       DSAStackTy::DSAVarData DVar =
18500           DSAStack->getTopDSA(D, /*FromParent=*/false);
18501       TopDVar = DVar;
18502       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18503       bool IsConstant = ElemType.isConstant(Context);
18504       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18505       //  A list item that specifies a given variable may not appear in more
18506       // than one clause on the same directive, except that a variable may be
18507       //  specified in both firstprivate and lastprivate clauses.
18508       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18509       // A list item may appear in a firstprivate or lastprivate clause but not
18510       // both.
18511       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18512           (isOpenMPDistributeDirective(CurrDir) ||
18513            DVar.CKind != OMPC_lastprivate) &&
18514           DVar.RefExpr) {
18515         Diag(ELoc, diag::err_omp_wrong_dsa)
18516             << getOpenMPClauseName(DVar.CKind)
18517             << getOpenMPClauseName(OMPC_firstprivate);
18518         reportOriginalDsa(*this, DSAStack, D, DVar);
18519         continue;
18520       }
18521 
18522       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18523       // in a Construct]
18524       //  Variables with the predetermined data-sharing attributes may not be
18525       //  listed in data-sharing attributes clauses, except for the cases
18526       //  listed below. For these exceptions only, listing a predetermined
18527       //  variable in a data-sharing attribute clause is allowed and overrides
18528       //  the variable's predetermined data-sharing attributes.
18529       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18530       // in a Construct, C/C++, p.2]
18531       //  Variables with const-qualified type having no mutable member may be
18532       //  listed in a firstprivate clause, even if they are static data members.
18533       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18534           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18535         Diag(ELoc, diag::err_omp_wrong_dsa)
18536             << getOpenMPClauseName(DVar.CKind)
18537             << getOpenMPClauseName(OMPC_firstprivate);
18538         reportOriginalDsa(*this, DSAStack, D, DVar);
18539         continue;
18540       }
18541 
18542       // OpenMP [2.9.3.4, Restrictions, p.2]
18543       //  A list item that is private within a parallel region must not appear
18544       //  in a firstprivate clause on a worksharing construct if any of the
18545       //  worksharing regions arising from the worksharing construct ever bind
18546       //  to any of the parallel regions arising from the parallel construct.
18547       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18548       // A list item that is private within a teams region must not appear in a
18549       // firstprivate clause on a distribute construct if any of the distribute
18550       // regions arising from the distribute construct ever bind to any of the
18551       // teams regions arising from the teams construct.
18552       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18553       // A list item that appears in a reduction clause of a teams construct
18554       // must not appear in a firstprivate clause on a distribute construct if
18555       // any of the distribute regions arising from the distribute construct
18556       // ever bind to any of the teams regions arising from the teams construct.
18557       if ((isOpenMPWorksharingDirective(CurrDir) ||
18558            isOpenMPDistributeDirective(CurrDir)) &&
18559           !isOpenMPParallelDirective(CurrDir) &&
18560           !isOpenMPTeamsDirective(CurrDir)) {
18561         DVar = DSAStack->getImplicitDSA(D, true);
18562         if (DVar.CKind != OMPC_shared &&
18563             (isOpenMPParallelDirective(DVar.DKind) ||
18564              isOpenMPTeamsDirective(DVar.DKind) ||
18565              DVar.DKind == OMPD_unknown)) {
18566           Diag(ELoc, diag::err_omp_required_access)
18567               << getOpenMPClauseName(OMPC_firstprivate)
18568               << getOpenMPClauseName(OMPC_shared);
18569           reportOriginalDsa(*this, DSAStack, D, DVar);
18570           continue;
18571         }
18572       }
18573       // OpenMP [2.9.3.4, Restrictions, p.3]
18574       //  A list item that appears in a reduction clause of a parallel construct
18575       //  must not appear in a firstprivate clause on a worksharing or task
18576       //  construct if any of the worksharing or task regions arising from the
18577       //  worksharing or task construct ever bind to any of the parallel regions
18578       //  arising from the parallel construct.
18579       // OpenMP [2.9.3.4, Restrictions, p.4]
18580       //  A list item that appears in a reduction clause in worksharing
18581       //  construct must not appear in a firstprivate clause in a task construct
18582       //  encountered during execution of any of the worksharing regions arising
18583       //  from the worksharing construct.
18584       if (isOpenMPTaskingDirective(CurrDir)) {
18585         DVar = DSAStack->hasInnermostDSA(
18586             D,
18587             [](OpenMPClauseKind C, bool AppliedToPointee) {
18588               return C == OMPC_reduction && !AppliedToPointee;
18589             },
18590             [](OpenMPDirectiveKind K) {
18591               return isOpenMPParallelDirective(K) ||
18592                      isOpenMPWorksharingDirective(K) ||
18593                      isOpenMPTeamsDirective(K);
18594             },
18595             /*FromParent=*/true);
18596         if (DVar.CKind == OMPC_reduction &&
18597             (isOpenMPParallelDirective(DVar.DKind) ||
18598              isOpenMPWorksharingDirective(DVar.DKind) ||
18599              isOpenMPTeamsDirective(DVar.DKind))) {
18600           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18601               << getOpenMPDirectiveName(DVar.DKind);
18602           reportOriginalDsa(*this, DSAStack, D, DVar);
18603           continue;
18604         }
18605       }
18606 
18607       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18608       // A list item cannot appear in both a map clause and a data-sharing
18609       // attribute clause on the same construct
18610       //
18611       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18612       // A list item cannot appear in both a map clause and a data-sharing
18613       // attribute clause on the same construct unless the construct is a
18614       // combined construct.
18615       if ((LangOpts.OpenMP <= 45 &&
18616            isOpenMPTargetExecutionDirective(CurrDir)) ||
18617           CurrDir == OMPD_target) {
18618         OpenMPClauseKind ConflictKind;
18619         if (DSAStack->checkMappableExprComponentListsForDecl(
18620                 VD, /*CurrentRegionOnly=*/true,
18621                 [&ConflictKind](
18622                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
18623                     OpenMPClauseKind WhereFoundClauseKind) {
18624                   ConflictKind = WhereFoundClauseKind;
18625                   return true;
18626                 })) {
18627           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18628               << getOpenMPClauseName(OMPC_firstprivate)
18629               << getOpenMPClauseName(ConflictKind)
18630               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18631           reportOriginalDsa(*this, DSAStack, D, DVar);
18632           continue;
18633         }
18634       }
18635     }
18636 
18637     // Variably modified types are not supported for tasks.
18638     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18639         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
18640       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18641           << getOpenMPClauseName(OMPC_firstprivate) << Type
18642           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18643       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18644                                VarDecl::DeclarationOnly;
18645       Diag(D->getLocation(),
18646            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18647           << D;
18648       continue;
18649     }
18650 
18651     Type = Type.getUnqualifiedType();
18652     VarDecl *VDPrivate =
18653         buildVarDecl(*this, ELoc, Type, D->getName(),
18654                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18655                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18656     // Generate helper private variable and initialize it with the value of the
18657     // original variable. The address of the original variable is replaced by
18658     // the address of the new private variable in the CodeGen. This new variable
18659     // is not added to IdResolver, so the code in the OpenMP region uses
18660     // original variable for proper diagnostics and variable capturing.
18661     Expr *VDInitRefExpr = nullptr;
18662     // For arrays generate initializer for single element and replace it by the
18663     // original array element in CodeGen.
18664     if (Type->isArrayType()) {
18665       VarDecl *VDInit =
18666           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18667       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18668       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18669       ElemType = ElemType.getUnqualifiedType();
18670       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18671                                          ".firstprivate.temp");
18672       InitializedEntity Entity =
18673           InitializedEntity::InitializeVariable(VDInitTemp);
18674       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18675 
18676       InitializationSequence InitSeq(*this, Entity, Kind, Init);
18677       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18678       if (Result.isInvalid())
18679         VDPrivate->setInvalidDecl();
18680       else
18681         VDPrivate->setInit(Result.getAs<Expr>());
18682       // Remove temp variable declaration.
18683       Context.Deallocate(VDInitTemp);
18684     } else {
18685       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18686                                      ".firstprivate.temp");
18687       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18688                                        RefExpr->getExprLoc());
18689       AddInitializerToDecl(VDPrivate,
18690                            DefaultLvalueConversion(VDInitRefExpr).get(),
18691                            /*DirectInit=*/false);
18692     }
18693     if (VDPrivate->isInvalidDecl()) {
18694       if (IsImplicitClause) {
18695         Diag(RefExpr->getExprLoc(),
18696              diag::note_omp_task_predetermined_firstprivate_here);
18697       }
18698       continue;
18699     }
18700     CurContext->addDecl(VDPrivate);
18701     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18702         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18703         RefExpr->getExprLoc());
18704     DeclRefExpr *Ref = nullptr;
18705     if (!VD && !CurContext->isDependentContext()) {
18706       if (TopDVar.CKind == OMPC_lastprivate) {
18707         Ref = TopDVar.PrivateCopy;
18708       } else {
18709         auto *FD = dyn_cast<FieldDecl>(D);
18710         VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18711         if (VD)
18712           Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18713                                  RefExpr->getExprLoc());
18714         else
18715           Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18716         if (VD || !isOpenMPCapturedDecl(D))
18717           ExprCaptures.push_back(Ref->getDecl());
18718       }
18719     }
18720     if (!IsImplicitClause)
18721       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18722     Vars.push_back((VD || CurContext->isDependentContext())
18723                        ? RefExpr->IgnoreParens()
18724                        : Ref);
18725     PrivateCopies.push_back(VDPrivateRefExpr);
18726     Inits.push_back(VDInitRefExpr);
18727   }
18728 
18729   if (Vars.empty())
18730     return nullptr;
18731 
18732   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18733                                        Vars, PrivateCopies, Inits,
18734                                        buildPreInits(Context, ExprCaptures));
18735 }
18736 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18737 OMPClause *Sema::ActOnOpenMPLastprivateClause(
18738     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18739     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18740     SourceLocation LParenLoc, SourceLocation EndLoc) {
18741   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18742     assert(ColonLoc.isValid() && "Colon location must be valid.");
18743     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18744         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18745                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
18746         << getOpenMPClauseName(OMPC_lastprivate);
18747     return nullptr;
18748   }
18749 
18750   SmallVector<Expr *, 8> Vars;
18751   SmallVector<Expr *, 8> SrcExprs;
18752   SmallVector<Expr *, 8> DstExprs;
18753   SmallVector<Expr *, 8> AssignmentOps;
18754   SmallVector<Decl *, 4> ExprCaptures;
18755   SmallVector<Expr *, 4> ExprPostUpdates;
18756   for (Expr *RefExpr : VarList) {
18757     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18758     SourceLocation ELoc;
18759     SourceRange ERange;
18760     Expr *SimpleRefExpr = RefExpr;
18761     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18762     if (Res.second) {
18763       // It will be analyzed later.
18764       Vars.push_back(RefExpr);
18765       SrcExprs.push_back(nullptr);
18766       DstExprs.push_back(nullptr);
18767       AssignmentOps.push_back(nullptr);
18768     }
18769     ValueDecl *D = Res.first;
18770     if (!D)
18771       continue;
18772 
18773     QualType Type = D->getType();
18774     auto *VD = dyn_cast<VarDecl>(D);
18775 
18776     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18777     //  A variable that appears in a lastprivate clause must not have an
18778     //  incomplete type or a reference type.
18779     if (RequireCompleteType(ELoc, Type,
18780                             diag::err_omp_lastprivate_incomplete_type))
18781       continue;
18782     Type = Type.getNonReferenceType();
18783 
18784     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18785     // A variable that is privatized must not have a const-qualified type
18786     // unless it is of class type with a mutable member. This restriction does
18787     // not apply to the firstprivate clause.
18788     //
18789     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18790     // A variable that appears in a lastprivate clause must not have a
18791     // const-qualified type unless it is of class type with a mutable member.
18792     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18793       continue;
18794 
18795     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18796     // A list item that appears in a lastprivate clause with the conditional
18797     // modifier must be a scalar variable.
18798     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18799       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18800       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18801                                VarDecl::DeclarationOnly;
18802       Diag(D->getLocation(),
18803            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18804           << D;
18805       continue;
18806     }
18807 
18808     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18809     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18810     // in a Construct]
18811     //  Variables with the predetermined data-sharing attributes may not be
18812     //  listed in data-sharing attributes clauses, except for the cases
18813     //  listed below.
18814     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18815     // A list item may appear in a firstprivate or lastprivate clause but not
18816     // both.
18817     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18818     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18819         (isOpenMPDistributeDirective(CurrDir) ||
18820          DVar.CKind != OMPC_firstprivate) &&
18821         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18822       Diag(ELoc, diag::err_omp_wrong_dsa)
18823           << getOpenMPClauseName(DVar.CKind)
18824           << getOpenMPClauseName(OMPC_lastprivate);
18825       reportOriginalDsa(*this, DSAStack, D, DVar);
18826       continue;
18827     }
18828 
18829     // OpenMP [2.14.3.5, Restrictions, p.2]
18830     // A list item that is private within a parallel region, or that appears in
18831     // the reduction clause of a parallel construct, must not appear in a
18832     // lastprivate clause on a worksharing construct if any of the corresponding
18833     // worksharing regions ever binds to any of the corresponding parallel
18834     // regions.
18835     DSAStackTy::DSAVarData TopDVar = DVar;
18836     if (isOpenMPWorksharingDirective(CurrDir) &&
18837         !isOpenMPParallelDirective(CurrDir) &&
18838         !isOpenMPTeamsDirective(CurrDir)) {
18839       DVar = DSAStack->getImplicitDSA(D, true);
18840       if (DVar.CKind != OMPC_shared) {
18841         Diag(ELoc, diag::err_omp_required_access)
18842             << getOpenMPClauseName(OMPC_lastprivate)
18843             << getOpenMPClauseName(OMPC_shared);
18844         reportOriginalDsa(*this, DSAStack, D, DVar);
18845         continue;
18846       }
18847     }
18848 
18849     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18850     //  A variable of class type (or array thereof) that appears in a
18851     //  lastprivate clause requires an accessible, unambiguous default
18852     //  constructor for the class type, unless the list item is also specified
18853     //  in a firstprivate clause.
18854     //  A variable of class type (or array thereof) that appears in a
18855     //  lastprivate clause requires an accessible, unambiguous copy assignment
18856     //  operator for the class type.
18857     Type = Context.getBaseElementType(Type).getNonReferenceType();
18858     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18859                                   Type.getUnqualifiedType(), ".lastprivate.src",
18860                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18861     DeclRefExpr *PseudoSrcExpr =
18862         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18863     VarDecl *DstVD =
18864         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18865                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18866     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18867     // For arrays generate assignment operation for single element and replace
18868     // it by the original array element in CodeGen.
18869     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18870                                          PseudoDstExpr, PseudoSrcExpr);
18871     if (AssignmentOp.isInvalid())
18872       continue;
18873     AssignmentOp =
18874         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18875     if (AssignmentOp.isInvalid())
18876       continue;
18877 
18878     DeclRefExpr *Ref = nullptr;
18879     if (!VD && !CurContext->isDependentContext()) {
18880       if (TopDVar.CKind == OMPC_firstprivate) {
18881         Ref = TopDVar.PrivateCopy;
18882       } else {
18883         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18884         if (!isOpenMPCapturedDecl(D))
18885           ExprCaptures.push_back(Ref->getDecl());
18886       }
18887       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18888           (!isOpenMPCapturedDecl(D) &&
18889            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18890         ExprResult RefRes = DefaultLvalueConversion(Ref);
18891         if (!RefRes.isUsable())
18892           continue;
18893         ExprResult PostUpdateRes =
18894             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18895                        RefRes.get());
18896         if (!PostUpdateRes.isUsable())
18897           continue;
18898         ExprPostUpdates.push_back(
18899             IgnoredValueConversions(PostUpdateRes.get()).get());
18900       }
18901     }
18902     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18903     Vars.push_back((VD || CurContext->isDependentContext())
18904                        ? RefExpr->IgnoreParens()
18905                        : Ref);
18906     SrcExprs.push_back(PseudoSrcExpr);
18907     DstExprs.push_back(PseudoDstExpr);
18908     AssignmentOps.push_back(AssignmentOp.get());
18909   }
18910 
18911   if (Vars.empty())
18912     return nullptr;
18913 
18914   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18915                                       Vars, SrcExprs, DstExprs, AssignmentOps,
18916                                       LPKind, LPKindLoc, ColonLoc,
18917                                       buildPreInits(Context, ExprCaptures),
18918                                       buildPostUpdate(*this, ExprPostUpdates));
18919 }
18920 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18921 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18922                                          SourceLocation StartLoc,
18923                                          SourceLocation LParenLoc,
18924                                          SourceLocation EndLoc) {
18925   SmallVector<Expr *, 8> Vars;
18926   for (Expr *RefExpr : VarList) {
18927     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18928     SourceLocation ELoc;
18929     SourceRange ERange;
18930     Expr *SimpleRefExpr = RefExpr;
18931     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18932     if (Res.second) {
18933       // It will be analyzed later.
18934       Vars.push_back(RefExpr);
18935     }
18936     ValueDecl *D = Res.first;
18937     if (!D)
18938       continue;
18939 
18940     auto *VD = dyn_cast<VarDecl>(D);
18941     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18942     // in a Construct]
18943     //  Variables with the predetermined data-sharing attributes may not be
18944     //  listed in data-sharing attributes clauses, except for the cases
18945     //  listed below. For these exceptions only, listing a predetermined
18946     //  variable in a data-sharing attribute clause is allowed and overrides
18947     //  the variable's predetermined data-sharing attributes.
18948     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18949     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18950         DVar.RefExpr) {
18951       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18952                                           << getOpenMPClauseName(OMPC_shared);
18953       reportOriginalDsa(*this, DSAStack, D, DVar);
18954       continue;
18955     }
18956 
18957     DeclRefExpr *Ref = nullptr;
18958     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18959       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18960     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18961     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18962                        ? RefExpr->IgnoreParens()
18963                        : Ref);
18964   }
18965 
18966   if (Vars.empty())
18967     return nullptr;
18968 
18969   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18970 }
18971 
18972 namespace {
18973 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18974   DSAStackTy *Stack;
18975 
18976 public:
VisitDeclRefExpr(DeclRefExpr * E)18977   bool VisitDeclRefExpr(DeclRefExpr *E) {
18978     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18979       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18980       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18981         return false;
18982       if (DVar.CKind != OMPC_unknown)
18983         return true;
18984       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18985           VD,
18986           [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18987             return isOpenMPPrivate(C) && !AppliedToPointee;
18988           },
18989           [](OpenMPDirectiveKind) { return true; },
18990           /*FromParent=*/true);
18991       return DVarPrivate.CKind != OMPC_unknown;
18992     }
18993     return false;
18994   }
VisitStmt(Stmt * S)18995   bool VisitStmt(Stmt *S) {
18996     for (Stmt *Child : S->children()) {
18997       if (Child && Visit(Child))
18998         return true;
18999     }
19000     return false;
19001   }
DSARefChecker(DSAStackTy * S)19002   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
19003 };
19004 } // namespace
19005 
19006 namespace {
19007 // Transform MemberExpression for specified FieldDecl of current class to
19008 // DeclRefExpr to specified OMPCapturedExprDecl.
19009 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
19010   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
19011   ValueDecl *Field = nullptr;
19012   DeclRefExpr *CapturedExpr = nullptr;
19013 
19014 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)19015   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
19016       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
19017 
TransformMemberExpr(MemberExpr * E)19018   ExprResult TransformMemberExpr(MemberExpr *E) {
19019     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
19020         E->getMemberDecl() == Field) {
19021       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
19022       return CapturedExpr;
19023     }
19024     return BaseTransform::TransformMemberExpr(E);
19025   }
getCapturedExpr()19026   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
19027 };
19028 } // namespace
19029 
19030 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)19031 static T filterLookupForUDReductionAndMapper(
19032     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
19033   for (U &Set : Lookups) {
19034     for (auto *D : Set) {
19035       if (T Res = Gen(cast<ValueDecl>(D)))
19036         return Res;
19037     }
19038   }
19039   return T();
19040 }
19041 
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)19042 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
19043   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
19044 
19045   for (auto *RD : D->redecls()) {
19046     // Don't bother with extra checks if we already know this one isn't visible.
19047     if (RD == D)
19048       continue;
19049 
19050     auto ND = cast<NamedDecl>(RD);
19051     if (LookupResult::isVisible(SemaRef, ND))
19052       return ND;
19053   }
19054 
19055   return nullptr;
19056 }
19057 
19058 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)19059 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
19060                         SourceLocation Loc, QualType Ty,
19061                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
19062   // Find all of the associated namespaces and classes based on the
19063   // arguments we have.
19064   Sema::AssociatedNamespaceSet AssociatedNamespaces;
19065   Sema::AssociatedClassSet AssociatedClasses;
19066   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
19067   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
19068                                              AssociatedClasses);
19069 
19070   // C++ [basic.lookup.argdep]p3:
19071   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
19072   //   and let Y be the lookup set produced by argument dependent
19073   //   lookup (defined as follows). If X contains [...] then Y is
19074   //   empty. Otherwise Y is the set of declarations found in the
19075   //   namespaces associated with the argument types as described
19076   //   below. The set of declarations found by the lookup of the name
19077   //   is the union of X and Y.
19078   //
19079   // Here, we compute Y and add its members to the overloaded
19080   // candidate set.
19081   for (auto *NS : AssociatedNamespaces) {
19082     //   When considering an associated namespace, the lookup is the
19083     //   same as the lookup performed when the associated namespace is
19084     //   used as a qualifier (3.4.3.2) except that:
19085     //
19086     //     -- Any using-directives in the associated namespace are
19087     //        ignored.
19088     //
19089     //     -- Any namespace-scope friend functions declared in
19090     //        associated classes are visible within their respective
19091     //        namespaces even if they are not visible during an ordinary
19092     //        lookup (11.4).
19093     DeclContext::lookup_result R = NS->lookup(Id.getName());
19094     for (auto *D : R) {
19095       auto *Underlying = D;
19096       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19097         Underlying = USD->getTargetDecl();
19098 
19099       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19100           !isa<OMPDeclareMapperDecl>(Underlying))
19101         continue;
19102 
19103       if (!SemaRef.isVisible(D)) {
19104         D = findAcceptableDecl(SemaRef, D);
19105         if (!D)
19106           continue;
19107         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19108           Underlying = USD->getTargetDecl();
19109       }
19110       Lookups.emplace_back();
19111       Lookups.back().addDecl(Underlying);
19112     }
19113   }
19114 }
19115 
19116 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)19117 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
19118                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
19119                          const DeclarationNameInfo &ReductionId, QualType Ty,
19120                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
19121   if (ReductionIdScopeSpec.isInvalid())
19122     return ExprError();
19123   SmallVector<UnresolvedSet<8>, 4> Lookups;
19124   if (S) {
19125     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19126     Lookup.suppressDiagnostics();
19127     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
19128       NamedDecl *D = Lookup.getRepresentativeDecl();
19129       do {
19130         S = S->getParent();
19131       } while (S && !S->isDeclScope(D));
19132       if (S)
19133         S = S->getParent();
19134       Lookups.emplace_back();
19135       Lookups.back().append(Lookup.begin(), Lookup.end());
19136       Lookup.clear();
19137     }
19138   } else if (auto *ULE =
19139                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19140     Lookups.push_back(UnresolvedSet<8>());
19141     Decl *PrevD = nullptr;
19142     for (NamedDecl *D : ULE->decls()) {
19143       if (D == PrevD)
19144         Lookups.push_back(UnresolvedSet<8>());
19145       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19146         Lookups.back().addDecl(DRD);
19147       PrevD = D;
19148     }
19149   }
19150   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
19151       Ty->isInstantiationDependentType() ||
19152       Ty->containsUnexpandedParameterPack() ||
19153       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19154         return !D->isInvalidDecl() &&
19155                (D->getType()->isDependentType() ||
19156                 D->getType()->isInstantiationDependentType() ||
19157                 D->getType()->containsUnexpandedParameterPack());
19158       })) {
19159     UnresolvedSet<8> ResSet;
19160     for (const UnresolvedSet<8> &Set : Lookups) {
19161       if (Set.empty())
19162         continue;
19163       ResSet.append(Set.begin(), Set.end());
19164       // The last item marks the end of all declarations at the specified scope.
19165       ResSet.addDecl(Set[Set.size() - 1]);
19166     }
19167     return UnresolvedLookupExpr::Create(
19168         SemaRef.Context, /*NamingClass=*/nullptr,
19169         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
19170         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
19171   }
19172   // Lookup inside the classes.
19173   // C++ [over.match.oper]p3:
19174   //   For a unary operator @ with an operand of a type whose
19175   //   cv-unqualified version is T1, and for a binary operator @ with
19176   //   a left operand of a type whose cv-unqualified version is T1 and
19177   //   a right operand of a type whose cv-unqualified version is T2,
19178   //   three sets of candidate functions, designated member
19179   //   candidates, non-member candidates and built-in candidates, are
19180   //   constructed as follows:
19181   //     -- If T1 is a complete class type or a class currently being
19182   //        defined, the set of member candidates is the result of the
19183   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
19184   //        the set of member candidates is empty.
19185   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19186   Lookup.suppressDiagnostics();
19187   if (const auto *TyRec = Ty->getAs<RecordType>()) {
19188     // Complete the type if it can be completed.
19189     // If the type is neither complete nor being defined, bail out now.
19190     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
19191         TyRec->getDecl()->getDefinition()) {
19192       Lookup.clear();
19193       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
19194       if (Lookup.empty()) {
19195         Lookups.emplace_back();
19196         Lookups.back().append(Lookup.begin(), Lookup.end());
19197       }
19198     }
19199   }
19200   // Perform ADL.
19201   if (SemaRef.getLangOpts().CPlusPlus)
19202     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
19203   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19204           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
19205             if (!D->isInvalidDecl() &&
19206                 SemaRef.Context.hasSameType(D->getType(), Ty))
19207               return D;
19208             return nullptr;
19209           }))
19210     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
19211                                     VK_LValue, Loc);
19212   if (SemaRef.getLangOpts().CPlusPlus) {
19213     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19214             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
19215               if (!D->isInvalidDecl() &&
19216                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
19217                   !Ty.isMoreQualifiedThan(D->getType()))
19218                 return D;
19219               return nullptr;
19220             })) {
19221       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19222                          /*DetectVirtual=*/false);
19223       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
19224         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19225                 VD->getType().getUnqualifiedType()))) {
19226           if (SemaRef.CheckBaseClassAccess(
19227                   Loc, VD->getType(), Ty, Paths.front(),
19228                   /*DiagID=*/0) != Sema::AR_inaccessible) {
19229             SemaRef.BuildBasePathArray(Paths, BasePath);
19230             return SemaRef.BuildDeclRefExpr(
19231                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
19232           }
19233         }
19234       }
19235     }
19236   }
19237   if (ReductionIdScopeSpec.isSet()) {
19238     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
19239         << Ty << Range;
19240     return ExprError();
19241   }
19242   return ExprEmpty();
19243 }
19244 
19245 namespace {
19246 /// Data for the reduction-based clauses.
19247 struct ReductionData {
19248   /// List of original reduction items.
19249   SmallVector<Expr *, 8> Vars;
19250   /// List of private copies of the reduction items.
19251   SmallVector<Expr *, 8> Privates;
19252   /// LHS expressions for the reduction_op expressions.
19253   SmallVector<Expr *, 8> LHSs;
19254   /// RHS expressions for the reduction_op expressions.
19255   SmallVector<Expr *, 8> RHSs;
19256   /// Reduction operation expression.
19257   SmallVector<Expr *, 8> ReductionOps;
19258   /// inscan copy operation expressions.
19259   SmallVector<Expr *, 8> InscanCopyOps;
19260   /// inscan copy temp array expressions for prefix sums.
19261   SmallVector<Expr *, 8> InscanCopyArrayTemps;
19262   /// inscan copy temp array element expressions for prefix sums.
19263   SmallVector<Expr *, 8> InscanCopyArrayElems;
19264   /// Taskgroup descriptors for the corresponding reduction items in
19265   /// in_reduction clauses.
19266   SmallVector<Expr *, 8> TaskgroupDescriptors;
19267   /// List of captures for clause.
19268   SmallVector<Decl *, 4> ExprCaptures;
19269   /// List of postupdate expressions.
19270   SmallVector<Expr *, 4> ExprPostUpdates;
19271   /// Reduction modifier.
19272   unsigned RedModifier = 0;
19273   ReductionData() = delete;
19274   /// Reserves required memory for the reduction data.
ReductionData__anon61cef30c5f11::ReductionData19275   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
19276     Vars.reserve(Size);
19277     Privates.reserve(Size);
19278     LHSs.reserve(Size);
19279     RHSs.reserve(Size);
19280     ReductionOps.reserve(Size);
19281     if (RedModifier == OMPC_REDUCTION_inscan) {
19282       InscanCopyOps.reserve(Size);
19283       InscanCopyArrayTemps.reserve(Size);
19284       InscanCopyArrayElems.reserve(Size);
19285     }
19286     TaskgroupDescriptors.reserve(Size);
19287     ExprCaptures.reserve(Size);
19288     ExprPostUpdates.reserve(Size);
19289   }
19290   /// Stores reduction item and reduction operation only (required for dependent
19291   /// reduction item).
push__anon61cef30c5f11::ReductionData19292   void push(Expr *Item, Expr *ReductionOp) {
19293     Vars.emplace_back(Item);
19294     Privates.emplace_back(nullptr);
19295     LHSs.emplace_back(nullptr);
19296     RHSs.emplace_back(nullptr);
19297     ReductionOps.emplace_back(ReductionOp);
19298     TaskgroupDescriptors.emplace_back(nullptr);
19299     if (RedModifier == OMPC_REDUCTION_inscan) {
19300       InscanCopyOps.push_back(nullptr);
19301       InscanCopyArrayTemps.push_back(nullptr);
19302       InscanCopyArrayElems.push_back(nullptr);
19303     }
19304   }
19305   /// Stores reduction data.
push__anon61cef30c5f11::ReductionData19306   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
19307             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
19308             Expr *CopyArrayElem) {
19309     Vars.emplace_back(Item);
19310     Privates.emplace_back(Private);
19311     LHSs.emplace_back(LHS);
19312     RHSs.emplace_back(RHS);
19313     ReductionOps.emplace_back(ReductionOp);
19314     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19315     if (RedModifier == OMPC_REDUCTION_inscan) {
19316       InscanCopyOps.push_back(CopyOp);
19317       InscanCopyArrayTemps.push_back(CopyArrayTemp);
19318       InscanCopyArrayElems.push_back(CopyArrayElem);
19319     } else {
19320       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
19321              CopyArrayElem == nullptr &&
19322              "Copy operation must be used for inscan reductions only.");
19323     }
19324   }
19325 };
19326 } // namespace
19327 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)19328 static bool checkOMPArraySectionConstantForReduction(
19329     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
19330     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
19331   const Expr *Length = OASE->getLength();
19332   if (Length == nullptr) {
19333     // For array sections of the form [1:] or [:], we would need to analyze
19334     // the lower bound...
19335     if (OASE->getColonLocFirst().isValid())
19336       return false;
19337 
19338     // This is an array subscript which has implicit length 1!
19339     SingleElement = true;
19340     ArraySizes.push_back(llvm::APSInt::get(1));
19341   } else {
19342     Expr::EvalResult Result;
19343     if (!Length->EvaluateAsInt(Result, Context))
19344       return false;
19345 
19346     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19347     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19348     ArraySizes.push_back(ConstantLengthValue);
19349   }
19350 
19351   // Get the base of this array section and walk up from there.
19352   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
19353 
19354   // We require length = 1 for all array sections except the right-most to
19355   // guarantee that the memory region is contiguous and has no holes in it.
19356   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
19357     Length = TempOASE->getLength();
19358     if (Length == nullptr) {
19359       // For array sections of the form [1:] or [:], we would need to analyze
19360       // the lower bound...
19361       if (OASE->getColonLocFirst().isValid())
19362         return false;
19363 
19364       // This is an array subscript which has implicit length 1!
19365       ArraySizes.push_back(llvm::APSInt::get(1));
19366     } else {
19367       Expr::EvalResult Result;
19368       if (!Length->EvaluateAsInt(Result, Context))
19369         return false;
19370 
19371       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19372       if (ConstantLengthValue.getSExtValue() != 1)
19373         return false;
19374 
19375       ArraySizes.push_back(ConstantLengthValue);
19376     }
19377     Base = TempOASE->getBase()->IgnoreParenImpCasts();
19378   }
19379 
19380   // If we have a single element, we don't need to add the implicit lengths.
19381   if (!SingleElement) {
19382     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
19383       // Has implicit length 1!
19384       ArraySizes.push_back(llvm::APSInt::get(1));
19385       Base = TempASE->getBase()->IgnoreParenImpCasts();
19386     }
19387   }
19388 
19389   // This array section can be privatized as a single value or as a constant
19390   // sized array.
19391   return true;
19392 }
19393 
19394 static BinaryOperatorKind
getRelatedCompoundReductionOp(BinaryOperatorKind BOK)19395 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
19396   if (BOK == BO_Add)
19397     return BO_AddAssign;
19398   if (BOK == BO_Mul)
19399     return BO_MulAssign;
19400   if (BOK == BO_And)
19401     return BO_AndAssign;
19402   if (BOK == BO_Or)
19403     return BO_OrAssign;
19404   if (BOK == BO_Xor)
19405     return BO_XorAssign;
19406   return BOK;
19407 }
19408 
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)19409 static bool actOnOMPReductionKindClause(
19410     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19411     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19412     SourceLocation ColonLoc, SourceLocation EndLoc,
19413     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19414     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19415   DeclarationName DN = ReductionId.getName();
19416   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
19417   BinaryOperatorKind BOK = BO_Comma;
19418 
19419   ASTContext &Context = S.Context;
19420   // OpenMP [2.14.3.6, reduction clause]
19421   // C
19422   // reduction-identifier is either an identifier or one of the following
19423   // operators: +, -, *,  &, |, ^, && and ||
19424   // C++
19425   // reduction-identifier is either an id-expression or one of the following
19426   // operators: +, -, *, &, |, ^, && and ||
19427   switch (OOK) {
19428   case OO_Plus:
19429     BOK = BO_Add;
19430     break;
19431   case OO_Minus:
19432     // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
19433     // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
19434     // reduction identifier.
19435     if (S.LangOpts.OpenMP > 52)
19436       BOK = BO_Comma;
19437     else
19438       BOK = BO_Add;
19439     break;
19440   case OO_Star:
19441     BOK = BO_Mul;
19442     break;
19443   case OO_Amp:
19444     BOK = BO_And;
19445     break;
19446   case OO_Pipe:
19447     BOK = BO_Or;
19448     break;
19449   case OO_Caret:
19450     BOK = BO_Xor;
19451     break;
19452   case OO_AmpAmp:
19453     BOK = BO_LAnd;
19454     break;
19455   case OO_PipePipe:
19456     BOK = BO_LOr;
19457     break;
19458   case OO_New:
19459   case OO_Delete:
19460   case OO_Array_New:
19461   case OO_Array_Delete:
19462   case OO_Slash:
19463   case OO_Percent:
19464   case OO_Tilde:
19465   case OO_Exclaim:
19466   case OO_Equal:
19467   case OO_Less:
19468   case OO_Greater:
19469   case OO_LessEqual:
19470   case OO_GreaterEqual:
19471   case OO_PlusEqual:
19472   case OO_MinusEqual:
19473   case OO_StarEqual:
19474   case OO_SlashEqual:
19475   case OO_PercentEqual:
19476   case OO_CaretEqual:
19477   case OO_AmpEqual:
19478   case OO_PipeEqual:
19479   case OO_LessLess:
19480   case OO_GreaterGreater:
19481   case OO_LessLessEqual:
19482   case OO_GreaterGreaterEqual:
19483   case OO_EqualEqual:
19484   case OO_ExclaimEqual:
19485   case OO_Spaceship:
19486   case OO_PlusPlus:
19487   case OO_MinusMinus:
19488   case OO_Comma:
19489   case OO_ArrowStar:
19490   case OO_Arrow:
19491   case OO_Call:
19492   case OO_Subscript:
19493   case OO_Conditional:
19494   case OO_Coawait:
19495   case NUM_OVERLOADED_OPERATORS:
19496     llvm_unreachable("Unexpected reduction identifier");
19497   case OO_None:
19498     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19499       if (II->isStr("max"))
19500         BOK = BO_GT;
19501       else if (II->isStr("min"))
19502         BOK = BO_LT;
19503     }
19504     break;
19505   }
19506 
19507   // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions
19508   // A reduction clause with the minus (-) operator was deprecated
19509   if (OOK == OO_Minus && S.LangOpts.OpenMP == 52)
19510     S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19511 
19512   SourceRange ReductionIdRange;
19513   if (ReductionIdScopeSpec.isValid())
19514     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19515   else
19516     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19517   ReductionIdRange.setEnd(ReductionId.getEndLoc());
19518 
19519   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19520   bool FirstIter = true;
19521   for (Expr *RefExpr : VarList) {
19522     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
19523     // OpenMP [2.1, C/C++]
19524     //  A list item is a variable or array section, subject to the restrictions
19525     //  specified in Section 2.4 on page 42 and in each of the sections
19526     // describing clauses and directives for which a list appears.
19527     // OpenMP  [2.14.3.3, Restrictions, p.1]
19528     //  A variable that is part of another variable (as an array or
19529     //  structure element) cannot appear in a private clause.
19530     if (!FirstIter && IR != ER)
19531       ++IR;
19532     FirstIter = false;
19533     SourceLocation ELoc;
19534     SourceRange ERange;
19535     Expr *SimpleRefExpr = RefExpr;
19536     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19537                               /*AllowArraySection=*/true);
19538     if (Res.second) {
19539       // Try to find 'declare reduction' corresponding construct before using
19540       // builtin/overloaded operators.
19541       QualType Type = Context.DependentTy;
19542       CXXCastPath BasePath;
19543       ExprResult DeclareReductionRef = buildDeclareReductionRef(
19544           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19545           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19546       Expr *ReductionOp = nullptr;
19547       if (S.CurContext->isDependentContext() &&
19548           (DeclareReductionRef.isUnset() ||
19549            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19550         ReductionOp = DeclareReductionRef.get();
19551       // It will be analyzed later.
19552       RD.push(RefExpr, ReductionOp);
19553     }
19554     ValueDecl *D = Res.first;
19555     if (!D)
19556       continue;
19557 
19558     Expr *TaskgroupDescriptor = nullptr;
19559     QualType Type;
19560     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19561     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19562     if (ASE) {
19563       Type = ASE->getType().getNonReferenceType();
19564     } else if (OASE) {
19565       QualType BaseType =
19566           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19567       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19568         Type = ATy->getElementType();
19569       else
19570         Type = BaseType->getPointeeType();
19571       Type = Type.getNonReferenceType();
19572     } else {
19573       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
19574     }
19575     auto *VD = dyn_cast<VarDecl>(D);
19576 
19577     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19578     //  A variable that appears in a private clause must not have an incomplete
19579     //  type or a reference type.
19580     if (S.RequireCompleteType(ELoc, D->getType(),
19581                               diag::err_omp_reduction_incomplete_type))
19582       continue;
19583     // OpenMP [2.14.3.6, reduction clause, Restrictions]
19584     // A list item that appears in a reduction clause must not be
19585     // const-qualified.
19586     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19587                                   /*AcceptIfMutable*/ false, ASE || OASE))
19588       continue;
19589 
19590     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19591     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19592     //  If a list-item is a reference type then it must bind to the same object
19593     //  for all threads of the team.
19594     if (!ASE && !OASE) {
19595       if (VD) {
19596         VarDecl *VDDef = VD->getDefinition();
19597         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
19598           DSARefChecker Check(Stack);
19599           if (Check.Visit(VDDef->getInit())) {
19600             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19601                 << getOpenMPClauseName(ClauseKind) << ERange;
19602             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19603             continue;
19604           }
19605         }
19606       }
19607 
19608       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19609       // in a Construct]
19610       //  Variables with the predetermined data-sharing attributes may not be
19611       //  listed in data-sharing attributes clauses, except for the cases
19612       //  listed below. For these exceptions only, listing a predetermined
19613       //  variable in a data-sharing attribute clause is allowed and overrides
19614       //  the variable's predetermined data-sharing attributes.
19615       // OpenMP [2.14.3.6, Restrictions, p.3]
19616       //  Any number of reduction clauses can be specified on the directive,
19617       //  but a list item can appear only once in the reduction clauses for that
19618       //  directive.
19619       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19620       if (DVar.CKind == OMPC_reduction) {
19621         S.Diag(ELoc, diag::err_omp_once_referenced)
19622             << getOpenMPClauseName(ClauseKind);
19623         if (DVar.RefExpr)
19624           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19625         continue;
19626       }
19627       if (DVar.CKind != OMPC_unknown) {
19628         S.Diag(ELoc, diag::err_omp_wrong_dsa)
19629             << getOpenMPClauseName(DVar.CKind)
19630             << getOpenMPClauseName(OMPC_reduction);
19631         reportOriginalDsa(S, Stack, D, DVar);
19632         continue;
19633       }
19634 
19635       // OpenMP [2.14.3.6, Restrictions, p.1]
19636       //  A list item that appears in a reduction clause of a worksharing
19637       //  construct must be shared in the parallel regions to which any of the
19638       //  worksharing regions arising from the worksharing construct bind.
19639       if (isOpenMPWorksharingDirective(CurrDir) &&
19640           !isOpenMPParallelDirective(CurrDir) &&
19641           !isOpenMPTeamsDirective(CurrDir)) {
19642         DVar = Stack->getImplicitDSA(D, true);
19643         if (DVar.CKind != OMPC_shared) {
19644           S.Diag(ELoc, diag::err_omp_required_access)
19645               << getOpenMPClauseName(OMPC_reduction)
19646               << getOpenMPClauseName(OMPC_shared);
19647           reportOriginalDsa(S, Stack, D, DVar);
19648           continue;
19649         }
19650       }
19651     } else {
19652       // Threadprivates cannot be shared between threads, so dignose if the base
19653       // is a threadprivate variable.
19654       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19655       if (DVar.CKind == OMPC_threadprivate) {
19656         S.Diag(ELoc, diag::err_omp_wrong_dsa)
19657             << getOpenMPClauseName(DVar.CKind)
19658             << getOpenMPClauseName(OMPC_reduction);
19659         reportOriginalDsa(S, Stack, D, DVar);
19660         continue;
19661       }
19662     }
19663 
19664     // Try to find 'declare reduction' corresponding construct before using
19665     // builtin/overloaded operators.
19666     CXXCastPath BasePath;
19667     ExprResult DeclareReductionRef = buildDeclareReductionRef(
19668         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19669         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19670     if (DeclareReductionRef.isInvalid())
19671       continue;
19672     if (S.CurContext->isDependentContext() &&
19673         (DeclareReductionRef.isUnset() ||
19674          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19675       RD.push(RefExpr, DeclareReductionRef.get());
19676       continue;
19677     }
19678     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19679       // Not allowed reduction identifier is found.
19680       if (S.LangOpts.OpenMP > 52)
19681         S.Diag(ReductionId.getBeginLoc(),
19682                diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19683             << Type << ReductionIdRange;
19684       else
19685         S.Diag(ReductionId.getBeginLoc(),
19686                diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19687             << Type << ReductionIdRange;
19688       continue;
19689     }
19690 
19691     // OpenMP [2.14.3.6, reduction clause, Restrictions]
19692     // The type of a list item that appears in a reduction clause must be valid
19693     // for the reduction-identifier. For a max or min reduction in C, the type
19694     // of the list item must be an allowed arithmetic data type: char, int,
19695     // float, double, or _Bool, possibly modified with long, short, signed, or
19696     // unsigned. For a max or min reduction in C++, the type of the list item
19697     // must be an allowed arithmetic data type: char, wchar_t, int, float,
19698     // double, or bool, possibly modified with long, short, signed, or unsigned.
19699     if (DeclareReductionRef.isUnset()) {
19700       if ((BOK == BO_GT || BOK == BO_LT) &&
19701           !(Type->isScalarType() ||
19702             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19703         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19704             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19705         if (!ASE && !OASE) {
19706           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19707                                    VarDecl::DeclarationOnly;
19708           S.Diag(D->getLocation(),
19709                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19710               << D;
19711         }
19712         continue;
19713       }
19714       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19715           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19716         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19717             << getOpenMPClauseName(ClauseKind);
19718         if (!ASE && !OASE) {
19719           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19720                                    VarDecl::DeclarationOnly;
19721           S.Diag(D->getLocation(),
19722                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19723               << D;
19724         }
19725         continue;
19726       }
19727     }
19728 
19729     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19730     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19731                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
19732     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19733                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
19734     QualType PrivateTy = Type;
19735 
19736     // Try if we can determine constant lengths for all array sections and avoid
19737     // the VLA.
19738     bool ConstantLengthOASE = false;
19739     if (OASE) {
19740       bool SingleElement;
19741       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19742       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19743           Context, OASE, SingleElement, ArraySizes);
19744 
19745       // If we don't have a single element, we must emit a constant array type.
19746       if (ConstantLengthOASE && !SingleElement) {
19747         for (llvm::APSInt &Size : ArraySizes)
19748           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19749                                                    ArraySizeModifier::Normal,
19750                                                    /*IndexTypeQuals=*/0);
19751       }
19752     }
19753 
19754     if ((OASE && !ConstantLengthOASE) ||
19755         (!OASE && !ASE &&
19756          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
19757       if (!Context.getTargetInfo().isVLASupported()) {
19758         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19759           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19760           S.Diag(ELoc, diag::note_vla_unsupported);
19761           continue;
19762         } else {
19763           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19764           S.targetDiag(ELoc, diag::note_vla_unsupported);
19765         }
19766       }
19767       // For arrays/array sections only:
19768       // Create pseudo array type for private copy. The size for this array will
19769       // be generated during codegen.
19770       // For array subscripts or single variables Private Ty is the same as Type
19771       // (type of the variable or single array element).
19772       PrivateTy = Context.getVariableArrayType(
19773           Type,
19774           new (Context)
19775               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19776           ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange());
19777     } else if (!ASE && !OASE &&
19778                Context.getAsArrayType(D->getType().getNonReferenceType())) {
19779       PrivateTy = D->getType().getNonReferenceType();
19780     }
19781     // Private copy.
19782     VarDecl *PrivateVD =
19783         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19784                      D->hasAttrs() ? &D->getAttrs() : nullptr,
19785                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19786     // Add initializer for private variable.
19787     Expr *Init = nullptr;
19788     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19789     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19790     if (DeclareReductionRef.isUsable()) {
19791       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19792       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19793       if (DRD->getInitializer()) {
19794         Init = DRDRef;
19795         RHSVD->setInit(DRDRef);
19796         RHSVD->setInitStyle(VarDecl::CallInit);
19797       }
19798     } else {
19799       switch (BOK) {
19800       case BO_Add:
19801       case BO_Xor:
19802       case BO_Or:
19803       case BO_LOr:
19804         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19805         if (Type->isScalarType() || Type->isAnyComplexType())
19806           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19807         break;
19808       case BO_Mul:
19809       case BO_LAnd:
19810         if (Type->isScalarType() || Type->isAnyComplexType()) {
19811           // '*' and '&&' reduction ops - initializer is '1'.
19812           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19813         }
19814         break;
19815       case BO_And: {
19816         // '&' reduction op - initializer is '~0'.
19817         QualType OrigType = Type;
19818         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19819           Type = ComplexTy->getElementType();
19820         if (Type->isRealFloatingType()) {
19821           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19822               Context.getFloatTypeSemantics(Type));
19823           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19824                                          Type, ELoc);
19825         } else if (Type->isScalarType()) {
19826           uint64_t Size = Context.getTypeSize(Type);
19827           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19828           llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19829           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19830         }
19831         if (Init && OrigType->isAnyComplexType()) {
19832           // Init = 0xFFFF + 0xFFFFi;
19833           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19834           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19835         }
19836         Type = OrigType;
19837         break;
19838       }
19839       case BO_LT:
19840       case BO_GT: {
19841         // 'min' reduction op - initializer is 'Largest representable number in
19842         // the reduction list item type'.
19843         // 'max' reduction op - initializer is 'Least representable number in
19844         // the reduction list item type'.
19845         if (Type->isIntegerType() || Type->isPointerType()) {
19846           bool IsSigned = Type->hasSignedIntegerRepresentation();
19847           uint64_t Size = Context.getTypeSize(Type);
19848           QualType IntTy =
19849               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19850           llvm::APInt InitValue =
19851               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19852                                         : llvm::APInt::getMinValue(Size)
19853               : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19854                              : llvm::APInt::getMaxValue(Size);
19855           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19856           if (Type->isPointerType()) {
19857             // Cast to pointer type.
19858             ExprResult CastExpr = S.BuildCStyleCastExpr(
19859                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19860             if (CastExpr.isInvalid())
19861               continue;
19862             Init = CastExpr.get();
19863           }
19864         } else if (Type->isRealFloatingType()) {
19865           llvm::APFloat InitValue = llvm::APFloat::getLargest(
19866               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19867           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19868                                          Type, ELoc);
19869         }
19870         break;
19871       }
19872       case BO_PtrMemD:
19873       case BO_PtrMemI:
19874       case BO_MulAssign:
19875       case BO_Div:
19876       case BO_Rem:
19877       case BO_Sub:
19878       case BO_Shl:
19879       case BO_Shr:
19880       case BO_LE:
19881       case BO_GE:
19882       case BO_EQ:
19883       case BO_NE:
19884       case BO_Cmp:
19885       case BO_AndAssign:
19886       case BO_XorAssign:
19887       case BO_OrAssign:
19888       case BO_Assign:
19889       case BO_AddAssign:
19890       case BO_SubAssign:
19891       case BO_DivAssign:
19892       case BO_RemAssign:
19893       case BO_ShlAssign:
19894       case BO_ShrAssign:
19895       case BO_Comma:
19896         llvm_unreachable("Unexpected reduction operation");
19897       }
19898     }
19899     if (Init && DeclareReductionRef.isUnset()) {
19900       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19901       // Store initializer for single element in private copy. Will be used
19902       // during codegen.
19903       PrivateVD->setInit(RHSVD->getInit());
19904       PrivateVD->setInitStyle(RHSVD->getInitStyle());
19905     } else if (!Init) {
19906       S.ActOnUninitializedDecl(RHSVD);
19907       // Store initializer for single element in private copy. Will be used
19908       // during codegen.
19909       PrivateVD->setInit(RHSVD->getInit());
19910       PrivateVD->setInitStyle(RHSVD->getInitStyle());
19911     }
19912     if (RHSVD->isInvalidDecl())
19913       continue;
19914     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19915       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19916           << Type << ReductionIdRange;
19917       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19918                                VarDecl::DeclarationOnly;
19919       S.Diag(D->getLocation(),
19920              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19921           << D;
19922       continue;
19923     }
19924     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19925     ExprResult ReductionOp;
19926     if (DeclareReductionRef.isUsable()) {
19927       QualType RedTy = DeclareReductionRef.get()->getType();
19928       QualType PtrRedTy = Context.getPointerType(RedTy);
19929       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19930       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19931       if (!BasePath.empty()) {
19932         LHS = S.DefaultLvalueConversion(LHS.get());
19933         RHS = S.DefaultLvalueConversion(RHS.get());
19934         LHS = ImplicitCastExpr::Create(
19935             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19936             LHS.get()->getValueKind(), FPOptionsOverride());
19937         RHS = ImplicitCastExpr::Create(
19938             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19939             RHS.get()->getValueKind(), FPOptionsOverride());
19940       }
19941       FunctionProtoType::ExtProtoInfo EPI;
19942       QualType Params[] = {PtrRedTy, PtrRedTy};
19943       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19944       auto *OVE = new (Context) OpaqueValueExpr(
19945           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19946           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19947       Expr *Args[] = {LHS.get(), RHS.get()};
19948       ReductionOp =
19949           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19950                            S.CurFPFeatureOverrides());
19951     } else {
19952       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19953       if (Type->isRecordType() && CombBOK != BOK) {
19954         Sema::TentativeAnalysisScope Trap(S);
19955         ReductionOp =
19956             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19957                          CombBOK, LHSDRE, RHSDRE);
19958       }
19959       if (!ReductionOp.isUsable()) {
19960         ReductionOp =
19961             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19962                          LHSDRE, RHSDRE);
19963         if (ReductionOp.isUsable()) {
19964           if (BOK != BO_LT && BOK != BO_GT) {
19965             ReductionOp =
19966                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19967                              BO_Assign, LHSDRE, ReductionOp.get());
19968           } else {
19969             auto *ConditionalOp = new (Context)
19970                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19971                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
19972             ReductionOp =
19973                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19974                              BO_Assign, LHSDRE, ConditionalOp);
19975           }
19976         }
19977       }
19978       if (ReductionOp.isUsable())
19979         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19980                                             /*DiscardedValue*/ false);
19981       if (!ReductionOp.isUsable())
19982         continue;
19983     }
19984 
19985     // Add copy operations for inscan reductions.
19986     // LHS = RHS;
19987     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19988     if (ClauseKind == OMPC_reduction &&
19989         RD.RedModifier == OMPC_REDUCTION_inscan) {
19990       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19991       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19992                                RHS.get());
19993       if (!CopyOpRes.isUsable())
19994         continue;
19995       CopyOpRes =
19996           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19997       if (!CopyOpRes.isUsable())
19998         continue;
19999       // For simd directive and simd-based directives in simd mode no need to
20000       // construct temp array, need just a single temp element.
20001       if (Stack->getCurrentDirective() == OMPD_simd ||
20002           (S.getLangOpts().OpenMPSimd &&
20003            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
20004         VarDecl *TempArrayVD =
20005             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
20006                          D->hasAttrs() ? &D->getAttrs() : nullptr);
20007         // Add a constructor to the temp decl.
20008         S.ActOnUninitializedDecl(TempArrayVD);
20009         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
20010       } else {
20011         // Build temp array for prefix sum.
20012         auto *Dim = new (S.Context)
20013             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
20014         QualType ArrayTy = S.Context.getVariableArrayType(
20015             PrivateTy, Dim, ArraySizeModifier::Normal,
20016             /*IndexTypeQuals=*/0, {ELoc, ELoc});
20017         VarDecl *TempArrayVD =
20018             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
20019                          D->hasAttrs() ? &D->getAttrs() : nullptr);
20020         // Add a constructor to the temp decl.
20021         S.ActOnUninitializedDecl(TempArrayVD);
20022         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
20023         TempArrayElem =
20024             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
20025         auto *Idx = new (S.Context)
20026             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
20027         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
20028                                                           ELoc, Idx, ELoc);
20029       }
20030     }
20031 
20032     // OpenMP [2.15.4.6, Restrictions, p.2]
20033     // A list item that appears in an in_reduction clause of a task construct
20034     // must appear in a task_reduction clause of a construct associated with a
20035     // taskgroup region that includes the participating task in its taskgroup
20036     // set. The construct associated with the innermost region that meets this
20037     // condition must specify the same reduction-identifier as the in_reduction
20038     // clause.
20039     if (ClauseKind == OMPC_in_reduction) {
20040       SourceRange ParentSR;
20041       BinaryOperatorKind ParentBOK;
20042       const Expr *ParentReductionOp = nullptr;
20043       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
20044       DSAStackTy::DSAVarData ParentBOKDSA =
20045           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
20046                                                   ParentBOKTD);
20047       DSAStackTy::DSAVarData ParentReductionOpDSA =
20048           Stack->getTopMostTaskgroupReductionData(
20049               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
20050       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
20051       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
20052       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
20053           (DeclareReductionRef.isUsable() && IsParentBOK) ||
20054           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
20055         bool EmitError = true;
20056         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
20057           llvm::FoldingSetNodeID RedId, ParentRedId;
20058           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
20059           DeclareReductionRef.get()->Profile(RedId, Context,
20060                                              /*Canonical=*/true);
20061           EmitError = RedId != ParentRedId;
20062         }
20063         if (EmitError) {
20064           S.Diag(ReductionId.getBeginLoc(),
20065                  diag::err_omp_reduction_identifier_mismatch)
20066               << ReductionIdRange << RefExpr->getSourceRange();
20067           S.Diag(ParentSR.getBegin(),
20068                  diag::note_omp_previous_reduction_identifier)
20069               << ParentSR
20070               << (IsParentBOK ? ParentBOKDSA.RefExpr
20071                               : ParentReductionOpDSA.RefExpr)
20072                      ->getSourceRange();
20073           continue;
20074         }
20075       }
20076       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
20077     }
20078 
20079     DeclRefExpr *Ref = nullptr;
20080     Expr *VarsExpr = RefExpr->IgnoreParens();
20081     if (!VD && !S.CurContext->isDependentContext()) {
20082       if (ASE || OASE) {
20083         TransformExprToCaptures RebuildToCapture(S, D);
20084         VarsExpr =
20085             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20086         Ref = RebuildToCapture.getCapturedExpr();
20087       } else {
20088         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
20089       }
20090       if (!S.isOpenMPCapturedDecl(D)) {
20091         RD.ExprCaptures.emplace_back(Ref->getDecl());
20092         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20093           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
20094           if (!RefRes.isUsable())
20095             continue;
20096           ExprResult PostUpdateRes =
20097               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20098                            RefRes.get());
20099           if (!PostUpdateRes.isUsable())
20100             continue;
20101           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
20102               Stack->getCurrentDirective() == OMPD_taskgroup) {
20103             S.Diag(RefExpr->getExprLoc(),
20104                    diag::err_omp_reduction_non_addressable_expression)
20105                 << RefExpr->getSourceRange();
20106             continue;
20107           }
20108           RD.ExprPostUpdates.emplace_back(
20109               S.IgnoredValueConversions(PostUpdateRes.get()).get());
20110         }
20111       }
20112     }
20113     // All reduction items are still marked as reduction (to do not increase
20114     // code base size).
20115     unsigned Modifier = RD.RedModifier;
20116     // Consider task_reductions as reductions with task modifier. Required for
20117     // correct analysis of in_reduction clauses.
20118     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
20119       Modifier = OMPC_REDUCTION_task;
20120     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20121                   ASE || OASE);
20122     if (Modifier == OMPC_REDUCTION_task &&
20123         (CurrDir == OMPD_taskgroup ||
20124          ((isOpenMPParallelDirective(CurrDir) ||
20125            isOpenMPWorksharingDirective(CurrDir)) &&
20126           !isOpenMPSimdDirective(CurrDir)))) {
20127       if (DeclareReductionRef.isUsable())
20128         Stack->addTaskgroupReductionData(D, ReductionIdRange,
20129                                          DeclareReductionRef.get());
20130       else
20131         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20132     }
20133     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
20134             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
20135             TempArrayElem.get());
20136   }
20137   return RD.Vars.empty();
20138 }
20139 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)20140 OMPClause *Sema::ActOnOpenMPReductionClause(
20141     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
20142     SourceLocation StartLoc, SourceLocation LParenLoc,
20143     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
20144     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20145     ArrayRef<Expr *> UnresolvedReductions) {
20146   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
20147     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20148         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
20149                                    /*Last=*/OMPC_REDUCTION_unknown)
20150         << getOpenMPClauseName(OMPC_reduction);
20151     return nullptr;
20152   }
20153   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
20154   // A reduction clause with the inscan reduction-modifier may only appear on a
20155   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
20156   // construct, a parallel worksharing-loop construct or a parallel
20157   // worksharing-loop SIMD construct.
20158   if (Modifier == OMPC_REDUCTION_inscan &&
20159       (DSAStack->getCurrentDirective() != OMPD_for &&
20160        DSAStack->getCurrentDirective() != OMPD_for_simd &&
20161        DSAStack->getCurrentDirective() != OMPD_simd &&
20162        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
20163        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
20164     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20165     return nullptr;
20166   }
20167 
20168   ReductionData RD(VarList.size(), Modifier);
20169   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
20170                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
20171                                   ReductionIdScopeSpec, ReductionId,
20172                                   UnresolvedReductions, RD))
20173     return nullptr;
20174 
20175   return OMPReductionClause::Create(
20176       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
20177       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20178       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20179       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20180       buildPreInits(Context, RD.ExprCaptures),
20181       buildPostUpdate(*this, RD.ExprPostUpdates));
20182 }
20183 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)20184 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
20185     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20186     SourceLocation ColonLoc, SourceLocation EndLoc,
20187     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20188     ArrayRef<Expr *> UnresolvedReductions) {
20189   ReductionData RD(VarList.size());
20190   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
20191                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
20192                                   ReductionIdScopeSpec, ReductionId,
20193                                   UnresolvedReductions, RD))
20194     return nullptr;
20195 
20196   return OMPTaskReductionClause::Create(
20197       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20198       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20199       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20200       buildPreInits(Context, RD.ExprCaptures),
20201       buildPostUpdate(*this, RD.ExprPostUpdates));
20202 }
20203 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)20204 OMPClause *Sema::ActOnOpenMPInReductionClause(
20205     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20206     SourceLocation ColonLoc, SourceLocation EndLoc,
20207     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20208     ArrayRef<Expr *> UnresolvedReductions) {
20209   ReductionData RD(VarList.size());
20210   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
20211                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
20212                                   ReductionIdScopeSpec, ReductionId,
20213                                   UnresolvedReductions, RD))
20214     return nullptr;
20215 
20216   return OMPInReductionClause::Create(
20217       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20218       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20219       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20220       buildPreInits(Context, RD.ExprCaptures),
20221       buildPostUpdate(*this, RD.ExprPostUpdates));
20222 }
20223 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)20224 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
20225                                      SourceLocation LinLoc) {
20226   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
20227       LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
20228     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
20229     return true;
20230   }
20231   return false;
20232 }
20233 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)20234 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
20235                                  OpenMPLinearClauseKind LinKind, QualType Type,
20236                                  bool IsDeclareSimd) {
20237   const auto *VD = dyn_cast_or_null<VarDecl>(D);
20238   // A variable must not have an incomplete type or a reference type.
20239   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
20240     return true;
20241   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
20242       !Type->isReferenceType()) {
20243     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20244         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
20245     return true;
20246   }
20247   Type = Type.getNonReferenceType();
20248 
20249   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
20250   // A variable that is privatized must not have a const-qualified type
20251   // unless it is of class type with a mutable member. This restriction does
20252   // not apply to the firstprivate clause, nor to the linear clause on
20253   // declarative directives (like declare simd).
20254   if (!IsDeclareSimd &&
20255       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
20256     return true;
20257 
20258   // A list item must be of integral or pointer type.
20259   Type = Type.getUnqualifiedType().getCanonicalType();
20260   const auto *Ty = Type.getTypePtrOrNull();
20261   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20262               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
20263     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
20264     if (D) {
20265       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20266                                VarDecl::DeclarationOnly;
20267       Diag(D->getLocation(),
20268            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20269           << D;
20270     }
20271     return true;
20272   }
20273   return false;
20274 }
20275 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation StepModifierLoc,SourceLocation EndLoc)20276 OMPClause *Sema::ActOnOpenMPLinearClause(
20277     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
20278     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
20279     SourceLocation LinLoc, SourceLocation ColonLoc,
20280     SourceLocation StepModifierLoc, SourceLocation EndLoc) {
20281   SmallVector<Expr *, 8> Vars;
20282   SmallVector<Expr *, 8> Privates;
20283   SmallVector<Expr *, 8> Inits;
20284   SmallVector<Decl *, 4> ExprCaptures;
20285   SmallVector<Expr *, 4> ExprPostUpdates;
20286   // OpenMP 5.2 [Section 5.4.6, linear clause]
20287   // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
20288   // 'ref'
20289   if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
20290       getLangOpts().OpenMP >= 52)
20291     Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20292   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
20293     LinKind = OMPC_LINEAR_val;
20294   for (Expr *RefExpr : VarList) {
20295     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20296     SourceLocation ELoc;
20297     SourceRange ERange;
20298     Expr *SimpleRefExpr = RefExpr;
20299     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20300     if (Res.second) {
20301       // It will be analyzed later.
20302       Vars.push_back(RefExpr);
20303       Privates.push_back(nullptr);
20304       Inits.push_back(nullptr);
20305     }
20306     ValueDecl *D = Res.first;
20307     if (!D)
20308       continue;
20309 
20310     QualType Type = D->getType();
20311     auto *VD = dyn_cast<VarDecl>(D);
20312 
20313     // OpenMP [2.14.3.7, linear clause]
20314     //  A list-item cannot appear in more than one linear clause.
20315     //  A list-item that appears in a linear clause cannot appear in any
20316     //  other data-sharing attribute clause.
20317     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20318     if (DVar.RefExpr) {
20319       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20320                                           << getOpenMPClauseName(OMPC_linear);
20321       reportOriginalDsa(*this, DSAStack, D, DVar);
20322       continue;
20323     }
20324 
20325     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
20326       continue;
20327     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20328 
20329     // Build private copy of original var.
20330     VarDecl *Private =
20331         buildVarDecl(*this, ELoc, Type, D->getName(),
20332                      D->hasAttrs() ? &D->getAttrs() : nullptr,
20333                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20334     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
20335     // Build var to save initial value.
20336     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
20337     Expr *InitExpr;
20338     DeclRefExpr *Ref = nullptr;
20339     if (!VD && !CurContext->isDependentContext()) {
20340       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20341       if (!isOpenMPCapturedDecl(D)) {
20342         ExprCaptures.push_back(Ref->getDecl());
20343         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20344           ExprResult RefRes = DefaultLvalueConversion(Ref);
20345           if (!RefRes.isUsable())
20346             continue;
20347           ExprResult PostUpdateRes =
20348               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
20349                          SimpleRefExpr, RefRes.get());
20350           if (!PostUpdateRes.isUsable())
20351             continue;
20352           ExprPostUpdates.push_back(
20353               IgnoredValueConversions(PostUpdateRes.get()).get());
20354         }
20355       }
20356     }
20357     if (LinKind == OMPC_LINEAR_uval)
20358       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20359     else
20360       InitExpr = VD ? SimpleRefExpr : Ref;
20361     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
20362                          /*DirectInit=*/false);
20363     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
20364 
20365     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20366     Vars.push_back((VD || CurContext->isDependentContext())
20367                        ? RefExpr->IgnoreParens()
20368                        : Ref);
20369     Privates.push_back(PrivateRef);
20370     Inits.push_back(InitRef);
20371   }
20372 
20373   if (Vars.empty())
20374     return nullptr;
20375 
20376   Expr *StepExpr = Step;
20377   Expr *CalcStepExpr = nullptr;
20378   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
20379       !Step->isInstantiationDependent() &&
20380       !Step->containsUnexpandedParameterPack()) {
20381     SourceLocation StepLoc = Step->getBeginLoc();
20382     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
20383     if (Val.isInvalid())
20384       return nullptr;
20385     StepExpr = Val.get();
20386 
20387     // Build var to save the step value.
20388     VarDecl *SaveVar =
20389         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
20390     ExprResult SaveRef =
20391         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
20392     ExprResult CalcStep =
20393         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
20394     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
20395 
20396     // Warn about zero linear step (it would be probably better specified as
20397     // making corresponding variables 'const').
20398     if (std::optional<llvm::APSInt> Result =
20399             StepExpr->getIntegerConstantExpr(Context)) {
20400       if (!Result->isNegative() && !Result->isStrictlyPositive())
20401         Diag(StepLoc, diag::warn_omp_linear_step_zero)
20402             << Vars[0] << (Vars.size() > 1);
20403     } else if (CalcStep.isUsable()) {
20404       // Calculate the step beforehand instead of doing this on each iteration.
20405       // (This is not used if the number of iterations may be kfold-ed).
20406       CalcStepExpr = CalcStep.get();
20407     }
20408   }
20409 
20410   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20411                                  ColonLoc, StepModifierLoc, EndLoc, Vars,
20412                                  Privates, Inits, StepExpr, CalcStepExpr,
20413                                  buildPreInits(Context, ExprCaptures),
20414                                  buildPostUpdate(*this, ExprPostUpdates));
20415 }
20416 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)20417 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
20418                                      Expr *NumIterations, Sema &SemaRef,
20419                                      Scope *S, DSAStackTy *Stack) {
20420   // Walk the vars and build update/final expressions for the CodeGen.
20421   SmallVector<Expr *, 8> Updates;
20422   SmallVector<Expr *, 8> Finals;
20423   SmallVector<Expr *, 8> UsedExprs;
20424   Expr *Step = Clause.getStep();
20425   Expr *CalcStep = Clause.getCalcStep();
20426   // OpenMP [2.14.3.7, linear clause]
20427   // If linear-step is not specified it is assumed to be 1.
20428   if (!Step)
20429     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
20430   else if (CalcStep)
20431     Step = cast<BinaryOperator>(CalcStep)->getLHS();
20432   bool HasErrors = false;
20433   auto CurInit = Clause.inits().begin();
20434   auto CurPrivate = Clause.privates().begin();
20435   OpenMPLinearClauseKind LinKind = Clause.getModifier();
20436   for (Expr *RefExpr : Clause.varlists()) {
20437     SourceLocation ELoc;
20438     SourceRange ERange;
20439     Expr *SimpleRefExpr = RefExpr;
20440     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20441     ValueDecl *D = Res.first;
20442     if (Res.second || !D) {
20443       Updates.push_back(nullptr);
20444       Finals.push_back(nullptr);
20445       HasErrors = true;
20446       continue;
20447     }
20448     auto &&Info = Stack->isLoopControlVariable(D);
20449     // OpenMP [2.15.11, distribute simd Construct]
20450     // A list item may not appear in a linear clause, unless it is the loop
20451     // iteration variable.
20452     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20453         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
20454       SemaRef.Diag(ELoc,
20455                    diag::err_omp_linear_distribute_var_non_loop_iteration);
20456       Updates.push_back(nullptr);
20457       Finals.push_back(nullptr);
20458       HasErrors = true;
20459       continue;
20460     }
20461     Expr *InitExpr = *CurInit;
20462 
20463     // Build privatized reference to the current linear var.
20464     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20465     Expr *CapturedRef;
20466     if (LinKind == OMPC_LINEAR_uval)
20467       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20468     else
20469       CapturedRef =
20470           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20471                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20472                            /*RefersToCapture=*/true);
20473 
20474     // Build update: Var = InitExpr + IV * Step
20475     ExprResult Update;
20476     if (!Info.first)
20477       Update = buildCounterUpdate(
20478           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20479           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20480     else
20481       Update = *CurPrivate;
20482     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20483                                          /*DiscardedValue*/ false);
20484 
20485     // Build final: Var = PrivCopy;
20486     ExprResult Final;
20487     if (!Info.first)
20488       Final = SemaRef.BuildBinOp(
20489           S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20490           SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20491     else
20492       Final = *CurPrivate;
20493     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20494                                         /*DiscardedValue*/ false);
20495 
20496     if (!Update.isUsable() || !Final.isUsable()) {
20497       Updates.push_back(nullptr);
20498       Finals.push_back(nullptr);
20499       UsedExprs.push_back(nullptr);
20500       HasErrors = true;
20501     } else {
20502       Updates.push_back(Update.get());
20503       Finals.push_back(Final.get());
20504       if (!Info.first)
20505         UsedExprs.push_back(SimpleRefExpr);
20506     }
20507     ++CurInit;
20508     ++CurPrivate;
20509   }
20510   if (Expr *S = Clause.getStep())
20511     UsedExprs.push_back(S);
20512   // Fill the remaining part with the nullptr.
20513   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20514   Clause.setUpdates(Updates);
20515   Clause.setFinals(Finals);
20516   Clause.setUsedExprs(UsedExprs);
20517   return HasErrors;
20518 }
20519 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)20520 OMPClause *Sema::ActOnOpenMPAlignedClause(
20521     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20522     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20523   SmallVector<Expr *, 8> Vars;
20524   for (Expr *RefExpr : VarList) {
20525     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20526     SourceLocation ELoc;
20527     SourceRange ERange;
20528     Expr *SimpleRefExpr = RefExpr;
20529     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20530     if (Res.second) {
20531       // It will be analyzed later.
20532       Vars.push_back(RefExpr);
20533     }
20534     ValueDecl *D = Res.first;
20535     if (!D)
20536       continue;
20537 
20538     QualType QType = D->getType();
20539     auto *VD = dyn_cast<VarDecl>(D);
20540 
20541     // OpenMP  [2.8.1, simd construct, Restrictions]
20542     // The type of list items appearing in the aligned clause must be
20543     // array, pointer, reference to array, or reference to pointer.
20544     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20545     const Type *Ty = QType.getTypePtrOrNull();
20546     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
20547       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20548           << QType << getLangOpts().CPlusPlus << ERange;
20549       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20550                                VarDecl::DeclarationOnly;
20551       Diag(D->getLocation(),
20552            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20553           << D;
20554       continue;
20555     }
20556 
20557     // OpenMP  [2.8.1, simd construct, Restrictions]
20558     // A list-item cannot appear in more than one aligned clause.
20559     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20560       Diag(ELoc, diag::err_omp_used_in_clause_twice)
20561           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20562       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20563           << getOpenMPClauseName(OMPC_aligned);
20564       continue;
20565     }
20566 
20567     DeclRefExpr *Ref = nullptr;
20568     if (!VD && isOpenMPCapturedDecl(D))
20569       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20570     Vars.push_back(DefaultFunctionArrayConversion(
20571                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20572                        .get());
20573   }
20574 
20575   // OpenMP [2.8.1, simd construct, Description]
20576   // The parameter of the aligned clause, alignment, must be a constant
20577   // positive integer expression.
20578   // If no optional parameter is specified, implementation-defined default
20579   // alignments for SIMD instructions on the target platforms are assumed.
20580   if (Alignment != nullptr) {
20581     ExprResult AlignResult =
20582         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20583     if (AlignResult.isInvalid())
20584       return nullptr;
20585     Alignment = AlignResult.get();
20586   }
20587   if (Vars.empty())
20588     return nullptr;
20589 
20590   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20591                                   EndLoc, Vars, Alignment);
20592 }
20593 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20594 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
20595                                          SourceLocation StartLoc,
20596                                          SourceLocation LParenLoc,
20597                                          SourceLocation EndLoc) {
20598   SmallVector<Expr *, 8> Vars;
20599   SmallVector<Expr *, 8> SrcExprs;
20600   SmallVector<Expr *, 8> DstExprs;
20601   SmallVector<Expr *, 8> AssignmentOps;
20602   for (Expr *RefExpr : VarList) {
20603     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
20604     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20605       // It will be analyzed later.
20606       Vars.push_back(RefExpr);
20607       SrcExprs.push_back(nullptr);
20608       DstExprs.push_back(nullptr);
20609       AssignmentOps.push_back(nullptr);
20610       continue;
20611     }
20612 
20613     SourceLocation ELoc = RefExpr->getExprLoc();
20614     // OpenMP [2.1, C/C++]
20615     //  A list item is a variable name.
20616     // OpenMP  [2.14.4.1, Restrictions, p.1]
20617     //  A list item that appears in a copyin clause must be threadprivate.
20618     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20619     if (!DE || !isa<VarDecl>(DE->getDecl())) {
20620       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20621           << 0 << RefExpr->getSourceRange();
20622       continue;
20623     }
20624 
20625     Decl *D = DE->getDecl();
20626     auto *VD = cast<VarDecl>(D);
20627 
20628     QualType Type = VD->getType();
20629     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
20630       // It will be analyzed later.
20631       Vars.push_back(DE);
20632       SrcExprs.push_back(nullptr);
20633       DstExprs.push_back(nullptr);
20634       AssignmentOps.push_back(nullptr);
20635       continue;
20636     }
20637 
20638     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20639     //  A list item that appears in a copyin clause must be threadprivate.
20640     if (!DSAStack->isThreadPrivate(VD)) {
20641       Diag(ELoc, diag::err_omp_required_access)
20642           << getOpenMPClauseName(OMPC_copyin)
20643           << getOpenMPDirectiveName(OMPD_threadprivate);
20644       continue;
20645     }
20646 
20647     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20648     //  A variable of class type (or array thereof) that appears in a
20649     //  copyin clause requires an accessible, unambiguous copy assignment
20650     //  operator for the class type.
20651     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20652     VarDecl *SrcVD =
20653         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20654                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20655     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20656         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20657     VarDecl *DstVD =
20658         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20659                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20660     DeclRefExpr *PseudoDstExpr =
20661         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20662     // For arrays generate assignment operation for single element and replace
20663     // it by the original array element in CodeGen.
20664     ExprResult AssignmentOp =
20665         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20666                    PseudoSrcExpr);
20667     if (AssignmentOp.isInvalid())
20668       continue;
20669     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20670                                        /*DiscardedValue*/ false);
20671     if (AssignmentOp.isInvalid())
20672       continue;
20673 
20674     DSAStack->addDSA(VD, DE, OMPC_copyin);
20675     Vars.push_back(DE);
20676     SrcExprs.push_back(PseudoSrcExpr);
20677     DstExprs.push_back(PseudoDstExpr);
20678     AssignmentOps.push_back(AssignmentOp.get());
20679   }
20680 
20681   if (Vars.empty())
20682     return nullptr;
20683 
20684   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20685                                  SrcExprs, DstExprs, AssignmentOps);
20686 }
20687 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20688 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20689                                               SourceLocation StartLoc,
20690                                               SourceLocation LParenLoc,
20691                                               SourceLocation EndLoc) {
20692   SmallVector<Expr *, 8> Vars;
20693   SmallVector<Expr *, 8> SrcExprs;
20694   SmallVector<Expr *, 8> DstExprs;
20695   SmallVector<Expr *, 8> AssignmentOps;
20696   for (Expr *RefExpr : VarList) {
20697     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20698     SourceLocation ELoc;
20699     SourceRange ERange;
20700     Expr *SimpleRefExpr = RefExpr;
20701     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20702     if (Res.second) {
20703       // It will be analyzed later.
20704       Vars.push_back(RefExpr);
20705       SrcExprs.push_back(nullptr);
20706       DstExprs.push_back(nullptr);
20707       AssignmentOps.push_back(nullptr);
20708     }
20709     ValueDecl *D = Res.first;
20710     if (!D)
20711       continue;
20712 
20713     QualType Type = D->getType();
20714     auto *VD = dyn_cast<VarDecl>(D);
20715 
20716     // OpenMP [2.14.4.2, Restrictions, p.2]
20717     //  A list item that appears in a copyprivate clause may not appear in a
20718     //  private or firstprivate clause on the single construct.
20719     if (!VD || !DSAStack->isThreadPrivate(VD)) {
20720       DSAStackTy::DSAVarData DVar =
20721           DSAStack->getTopDSA(D, /*FromParent=*/false);
20722       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20723           DVar.RefExpr) {
20724         Diag(ELoc, diag::err_omp_wrong_dsa)
20725             << getOpenMPClauseName(DVar.CKind)
20726             << getOpenMPClauseName(OMPC_copyprivate);
20727         reportOriginalDsa(*this, DSAStack, D, DVar);
20728         continue;
20729       }
20730 
20731       // OpenMP [2.11.4.2, Restrictions, p.1]
20732       //  All list items that appear in a copyprivate clause must be either
20733       //  threadprivate or private in the enclosing context.
20734       if (DVar.CKind == OMPC_unknown) {
20735         DVar = DSAStack->getImplicitDSA(D, false);
20736         if (DVar.CKind == OMPC_shared) {
20737           Diag(ELoc, diag::err_omp_required_access)
20738               << getOpenMPClauseName(OMPC_copyprivate)
20739               << "threadprivate or private in the enclosing context";
20740           reportOriginalDsa(*this, DSAStack, D, DVar);
20741           continue;
20742         }
20743       }
20744     }
20745 
20746     // Variably modified types are not supported.
20747     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
20748       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20749           << getOpenMPClauseName(OMPC_copyprivate) << Type
20750           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20751       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20752                                VarDecl::DeclarationOnly;
20753       Diag(D->getLocation(),
20754            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20755           << D;
20756       continue;
20757     }
20758 
20759     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20760     //  A variable of class type (or array thereof) that appears in a
20761     //  copyin clause requires an accessible, unambiguous copy assignment
20762     //  operator for the class type.
20763     Type = Context.getBaseElementType(Type.getNonReferenceType())
20764                .getUnqualifiedType();
20765     VarDecl *SrcVD =
20766         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20767                      D->hasAttrs() ? &D->getAttrs() : nullptr);
20768     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20769     VarDecl *DstVD =
20770         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20771                      D->hasAttrs() ? &D->getAttrs() : nullptr);
20772     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20773     ExprResult AssignmentOp = BuildBinOp(
20774         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20775     if (AssignmentOp.isInvalid())
20776       continue;
20777     AssignmentOp =
20778         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20779     if (AssignmentOp.isInvalid())
20780       continue;
20781 
20782     // No need to mark vars as copyprivate, they are already threadprivate or
20783     // implicitly private.
20784     assert(VD || isOpenMPCapturedDecl(D));
20785     Vars.push_back(
20786         VD ? RefExpr->IgnoreParens()
20787            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20788     SrcExprs.push_back(PseudoSrcExpr);
20789     DstExprs.push_back(PseudoDstExpr);
20790     AssignmentOps.push_back(AssignmentOp.get());
20791   }
20792 
20793   if (Vars.empty())
20794     return nullptr;
20795 
20796   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20797                                       Vars, SrcExprs, DstExprs, AssignmentOps);
20798 }
20799 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20800 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20801                                         SourceLocation StartLoc,
20802                                         SourceLocation LParenLoc,
20803                                         SourceLocation EndLoc) {
20804   if (VarList.empty())
20805     return nullptr;
20806 
20807   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20808 }
20809 
20810 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)20811 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20812                            bool Diagnose = true) {
20813   QualType OMPDependT = Stack->getOMPDependT();
20814   if (!OMPDependT.isNull())
20815     return true;
20816   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20817   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20818   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20819     if (Diagnose)
20820       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20821     return false;
20822   }
20823   Stack->setOMPDependT(PT.get());
20824   return true;
20825 }
20826 
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20827 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20828                                          SourceLocation LParenLoc,
20829                                          SourceLocation EndLoc) {
20830   if (!Depobj)
20831     return nullptr;
20832 
20833   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20834 
20835   // OpenMP 5.0, 2.17.10.1 depobj Construct
20836   // depobj is an lvalue expression of type omp_depend_t.
20837   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20838       !Depobj->isInstantiationDependent() &&
20839       !Depobj->containsUnexpandedParameterPack() &&
20840       (OMPDependTFound &&
20841        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
20842                                    /*CompareUnqualified=*/true))) {
20843     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20844         << 0 << Depobj->getType() << Depobj->getSourceRange();
20845   }
20846 
20847   if (!Depobj->isLValue()) {
20848     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20849         << 1 << Depobj->getSourceRange();
20850   }
20851 
20852   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20853 }
20854 
20855 namespace {
20856 // Utility struct that gathers the related info for doacross clause.
20857 struct DoacrossDataInfoTy {
20858   // The list of expressions.
20859   SmallVector<Expr *, 8> Vars;
20860   // The OperatorOffset for doacross loop.
20861   DSAStackTy::OperatorOffsetTy OpsOffs;
20862   // The depended loop count.
20863   llvm::APSInt TotalDepCount;
20864 };
20865 } // namespace
20866 static DoacrossDataInfoTy
ProcessOpenMPDoacrossClauseCommon(Sema & SemaRef,bool IsSource,ArrayRef<Expr * > VarList,DSAStackTy * Stack,SourceLocation EndLoc)20867 ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource,
20868                                   ArrayRef<Expr *> VarList, DSAStackTy *Stack,
20869                                   SourceLocation EndLoc) {
20870 
20871   SmallVector<Expr *, 8> Vars;
20872   DSAStackTy::OperatorOffsetTy OpsOffs;
20873   llvm::APSInt DepCounter(/*BitWidth=*/32);
20874   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20875 
20876   if (const Expr *OrderedCountExpr =
20877           Stack->getParentOrderedRegionParam().first) {
20878     TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context);
20879     TotalDepCount.setIsUnsigned(/*Val=*/true);
20880   }
20881 
20882   for (Expr *RefExpr : VarList) {
20883     assert(RefExpr && "NULL expr in OpenMP doacross clause.");
20884     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20885       // It will be analyzed later.
20886       Vars.push_back(RefExpr);
20887       continue;
20888     }
20889 
20890     SourceLocation ELoc = RefExpr->getExprLoc();
20891     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20892     if (!IsSource) {
20893       if (Stack->getParentOrderedRegionParam().first &&
20894           DepCounter >= TotalDepCount) {
20895         SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20896         continue;
20897       }
20898       ++DepCounter;
20899       // OpenMP  [2.13.9, Summary]
20900       // depend(dependence-type : vec), where dependence-type is:
20901       // 'sink' and where vec is the iteration vector, which has the form:
20902       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20903       // where n is the value specified by the ordered clause in the loop
20904       // directive, xi denotes the loop iteration variable of the i-th nested
20905       // loop associated with the loop directive, and di is a constant
20906       // non-negative integer.
20907       if (SemaRef.CurContext->isDependentContext()) {
20908         // It will be analyzed later.
20909         Vars.push_back(RefExpr);
20910         continue;
20911       }
20912       SimpleExpr = SimpleExpr->IgnoreImplicit();
20913       OverloadedOperatorKind OOK = OO_None;
20914       SourceLocation OOLoc;
20915       Expr *LHS = SimpleExpr;
20916       Expr *RHS = nullptr;
20917       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20918         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20919         OOLoc = BO->getOperatorLoc();
20920         LHS = BO->getLHS()->IgnoreParenImpCasts();
20921         RHS = BO->getRHS()->IgnoreParenImpCasts();
20922       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20923         OOK = OCE->getOperator();
20924         OOLoc = OCE->getOperatorLoc();
20925         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20926         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20927       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20928         OOK = MCE->getMethodDecl()
20929                   ->getNameInfo()
20930                   .getName()
20931                   .getCXXOverloadedOperator();
20932         OOLoc = MCE->getCallee()->getExprLoc();
20933         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20934         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20935       }
20936       SourceLocation ELoc;
20937       SourceRange ERange;
20938       auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange);
20939       if (Res.second) {
20940         // It will be analyzed later.
20941         Vars.push_back(RefExpr);
20942       }
20943       ValueDecl *D = Res.first;
20944       if (!D)
20945         continue;
20946 
20947       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20948         SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20949         continue;
20950       }
20951       if (RHS) {
20952         ExprResult RHSRes = SemaRef.VerifyPositiveIntegerConstantInClause(
20953             RHS, OMPC_depend, /*StrictlyPositive=*/false);
20954         if (RHSRes.isInvalid())
20955           continue;
20956       }
20957       if (!SemaRef.CurContext->isDependentContext() &&
20958           Stack->getParentOrderedRegionParam().first &&
20959           DepCounter != Stack->isParentLoopControlVariable(D).first) {
20960         const ValueDecl *VD =
20961             Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
20962         if (VD)
20963           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20964               << 1 << VD;
20965         else
20966           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20967               << 0;
20968         continue;
20969       }
20970       OpsOffs.emplace_back(RHS, OOK);
20971     }
20972     Vars.push_back(RefExpr->IgnoreParenImpCasts());
20973   }
20974   if (!SemaRef.CurContext->isDependentContext() && !IsSource &&
20975       TotalDepCount > VarList.size() &&
20976       Stack->getParentOrderedRegionParam().first &&
20977       Stack->getParentLoopControlVariable(VarList.size() + 1)) {
20978     SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20979         << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
20980   }
20981   return {Vars, OpsOffs, TotalDepCount};
20982 }
20983 
20984 OMPClause *
ActOnOpenMPDependClause(const OMPDependClause::DependDataTy & Data,Expr * DepModifier,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20985 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20986                               Expr *DepModifier, ArrayRef<Expr *> VarList,
20987                               SourceLocation StartLoc, SourceLocation LParenLoc,
20988                               SourceLocation EndLoc) {
20989   OpenMPDependClauseKind DepKind = Data.DepKind;
20990   SourceLocation DepLoc = Data.DepLoc;
20991   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20992       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20993     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20994         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20995     return nullptr;
20996   }
20997   if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20998       DepKind == OMPC_DEPEND_mutexinoutset) {
20999     Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
21000     return nullptr;
21001   }
21002   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
21003        DSAStack->getCurrentDirective() == OMPD_depobj) &&
21004       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
21005        DepKind == OMPC_DEPEND_sink ||
21006        ((LangOpts.OpenMP < 50 ||
21007          DSAStack->getCurrentDirective() == OMPD_depobj) &&
21008         DepKind == OMPC_DEPEND_depobj))) {
21009     SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
21010                                        OMPC_DEPEND_outallmemory,
21011                                        OMPC_DEPEND_inoutallmemory};
21012     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
21013       Except.push_back(OMPC_DEPEND_depobj);
21014     if (LangOpts.OpenMP < 51)
21015       Except.push_back(OMPC_DEPEND_inoutset);
21016     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
21017                                ? "depend modifier(iterator) or "
21018                                : "";
21019     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
21020         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
21021                                               /*Last=*/OMPC_DEPEND_unknown,
21022                                               Except)
21023         << getOpenMPClauseName(OMPC_depend);
21024     return nullptr;
21025   }
21026   if (DepModifier &&
21027       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
21028     Diag(DepModifier->getExprLoc(),
21029          diag::err_omp_depend_sink_source_with_modifier);
21030     return nullptr;
21031   }
21032   if (DepModifier &&
21033       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
21034     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
21035 
21036   SmallVector<Expr *, 8> Vars;
21037   DSAStackTy::OperatorOffsetTy OpsOffs;
21038   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
21039 
21040   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
21041     DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
21042         *this, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc);
21043     Vars = VarOffset.Vars;
21044     OpsOffs = VarOffset.OpsOffs;
21045     TotalDepCount = VarOffset.TotalDepCount;
21046   } else {
21047     for (Expr *RefExpr : VarList) {
21048       assert(RefExpr && "NULL expr in OpenMP shared clause.");
21049       if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21050         // It will be analyzed later.
21051         Vars.push_back(RefExpr);
21052         continue;
21053       }
21054 
21055       SourceLocation ELoc = RefExpr->getExprLoc();
21056       Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
21057       if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
21058         bool OMPDependTFound = LangOpts.OpenMP >= 50;
21059         if (OMPDependTFound)
21060           OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
21061                                            DepKind == OMPC_DEPEND_depobj);
21062         if (DepKind == OMPC_DEPEND_depobj) {
21063           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21064           // List items used in depend clauses with the depobj dependence type
21065           // must be expressions of the omp_depend_t type.
21066           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21067               !RefExpr->isInstantiationDependent() &&
21068               !RefExpr->containsUnexpandedParameterPack() &&
21069               (OMPDependTFound &&
21070                !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
21071                                                RefExpr->getType()))) {
21072             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21073                 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21074             continue;
21075           }
21076           if (!RefExpr->isLValue()) {
21077             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21078                 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21079             continue;
21080           }
21081         } else {
21082           // OpenMP 5.0 [2.17.11, Restrictions]
21083           // List items used in depend clauses cannot be zero-length array
21084           // sections.
21085           QualType ExprTy = RefExpr->getType().getNonReferenceType();
21086           const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
21087           if (OASE) {
21088             QualType BaseType =
21089                 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21090             if (BaseType.isNull())
21091               return nullptr;
21092             if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21093               ExprTy = ATy->getElementType();
21094             else
21095               ExprTy = BaseType->getPointeeType();
21096             ExprTy = ExprTy.getNonReferenceType();
21097             const Expr *Length = OASE->getLength();
21098             Expr::EvalResult Result;
21099             if (Length && !Length->isValueDependent() &&
21100                 Length->EvaluateAsInt(Result, Context) &&
21101                 Result.Val.getInt().isZero()) {
21102               Diag(ELoc,
21103                    diag::err_omp_depend_zero_length_array_section_not_allowed)
21104                   << SimpleExpr->getSourceRange();
21105               continue;
21106             }
21107           }
21108 
21109           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21110           // List items used in depend clauses with the in, out, inout,
21111           // inoutset, or mutexinoutset dependence types cannot be
21112           // expressions of the omp_depend_t type.
21113           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21114               !RefExpr->isInstantiationDependent() &&
21115               !RefExpr->containsUnexpandedParameterPack() &&
21116               (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
21117                (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() ==
21118                                        ExprTy.getTypePtr()))) {
21119             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21120                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
21121                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21122             continue;
21123           }
21124 
21125           auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21126           if (ASE && !ASE->getBase()->isTypeDependent() &&
21127               !ASE->getBase()
21128                    ->getType()
21129                    .getNonReferenceType()
21130                    ->isPointerType() &&
21131               !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
21132             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21133                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
21134                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21135             continue;
21136           }
21137 
21138           ExprResult Res;
21139           {
21140             Sema::TentativeAnalysisScope Trap(*this);
21141             Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
21142                                        RefExpr->IgnoreParenImpCasts());
21143           }
21144           if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21145               !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21146             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21147                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
21148                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21149             continue;
21150           }
21151         }
21152       }
21153       Vars.push_back(RefExpr->IgnoreParenImpCasts());
21154     }
21155   }
21156 
21157   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
21158       DepKind != OMPC_DEPEND_outallmemory &&
21159       DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
21160     return nullptr;
21161 
21162   auto *C = OMPDependClause::Create(
21163       Context, StartLoc, LParenLoc, EndLoc,
21164       {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
21165       TotalDepCount.getZExtValue());
21166   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
21167       DSAStack->isParentOrderedRegion())
21168     DSAStack->addDoacrossDependClause(C, OpsOffs);
21169   return C;
21170 }
21171 
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)21172 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
21173                                          Expr *Device, SourceLocation StartLoc,
21174                                          SourceLocation LParenLoc,
21175                                          SourceLocation ModifierLoc,
21176                                          SourceLocation EndLoc) {
21177   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
21178          "Unexpected device modifier in OpenMP < 50.");
21179 
21180   bool ErrorFound = false;
21181   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
21182     std::string Values =
21183         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
21184     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21185         << Values << getOpenMPClauseName(OMPC_device);
21186     ErrorFound = true;
21187   }
21188 
21189   Expr *ValExpr = Device;
21190   Stmt *HelperValStmt = nullptr;
21191 
21192   // OpenMP [2.9.1, Restrictions]
21193   // The device expression must evaluate to a non-negative integer value.
21194   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
21195                                           /*StrictlyPositive=*/false) ||
21196                ErrorFound;
21197   if (ErrorFound)
21198     return nullptr;
21199 
21200   // OpenMP 5.0 [2.12.5, Restrictions]
21201   // In case of ancestor device-modifier, a requires directive with
21202   // the reverse_offload clause must be specified.
21203   if (Modifier == OMPC_DEVICE_ancestor) {
21204     if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
21205       targetDiag(
21206           StartLoc,
21207           diag::err_omp_device_ancestor_without_requires_reverse_offload);
21208       ErrorFound = true;
21209     }
21210   }
21211 
21212   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21213   OpenMPDirectiveKind CaptureRegion =
21214       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
21215   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21216     ValExpr = MakeFullExpr(ValExpr).get();
21217     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21218     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21219     HelperValStmt = buildPreInits(Context, Captures);
21220   }
21221 
21222   return new (Context)
21223       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21224                       LParenLoc, ModifierLoc, EndLoc);
21225 }
21226 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)21227 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
21228                               DSAStackTy *Stack, QualType QTy,
21229                               bool FullCheck = true) {
21230   if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
21231     return false;
21232   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
21233       !QTy.isTriviallyCopyableType(SemaRef.Context))
21234     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21235   return true;
21236 }
21237 
21238 /// Return true if it can be proven that the provided array expression
21239 /// (array section or array subscript) does NOT specify the whole size of the
21240 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)21241 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
21242                                                         const Expr *E,
21243                                                         QualType BaseQTy) {
21244   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21245 
21246   // If this is an array subscript, it refers to the whole size if the size of
21247   // the dimension is constant and equals 1. Also, an array section assumes the
21248   // format of an array subscript if no colon is used.
21249   if (isa<ArraySubscriptExpr>(E) ||
21250       (OASE && OASE->getColonLocFirst().isInvalid())) {
21251     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21252       return ATy->getSize().getSExtValue() != 1;
21253     // Size can't be evaluated statically.
21254     return false;
21255   }
21256 
21257   assert(OASE && "Expecting array section if not an array subscript.");
21258   const Expr *LowerBound = OASE->getLowerBound();
21259   const Expr *Length = OASE->getLength();
21260 
21261   // If there is a lower bound that does not evaluates to zero, we are not
21262   // covering the whole dimension.
21263   if (LowerBound) {
21264     Expr::EvalResult Result;
21265     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
21266       return false; // Can't get the integer value as a constant.
21267 
21268     llvm::APSInt ConstLowerBound = Result.Val.getInt();
21269     if (ConstLowerBound.getSExtValue())
21270       return true;
21271   }
21272 
21273   // If we don't have a length we covering the whole dimension.
21274   if (!Length)
21275     return false;
21276 
21277   // If the base is a pointer, we don't have a way to get the size of the
21278   // pointee.
21279   if (BaseQTy->isPointerType())
21280     return false;
21281 
21282   // We can only check if the length is the same as the size of the dimension
21283   // if we have a constant array.
21284   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
21285   if (!CATy)
21286     return false;
21287 
21288   Expr::EvalResult Result;
21289   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21290     return false; // Can't get the integer value as a constant.
21291 
21292   llvm::APSInt ConstLength = Result.Val.getInt();
21293   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
21294 }
21295 
21296 // Return true if it can be proven that the provided array expression (array
21297 // section or array subscript) does NOT specify a single element of the array
21298 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)21299 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
21300                                                         const Expr *E,
21301                                                         QualType BaseQTy) {
21302   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21303 
21304   // An array subscript always refer to a single element. Also, an array section
21305   // assumes the format of an array subscript if no colon is used.
21306   if (isa<ArraySubscriptExpr>(E) ||
21307       (OASE && OASE->getColonLocFirst().isInvalid()))
21308     return false;
21309 
21310   assert(OASE && "Expecting array section if not an array subscript.");
21311   const Expr *Length = OASE->getLength();
21312 
21313   // If we don't have a length we have to check if the array has unitary size
21314   // for this dimension. Also, we should always expect a length if the base type
21315   // is pointer.
21316   if (!Length) {
21317     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21318       return ATy->getSize().getSExtValue() != 1;
21319     // We cannot assume anything.
21320     return false;
21321   }
21322 
21323   // Check if the length evaluates to 1.
21324   Expr::EvalResult Result;
21325   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21326     return false; // Can't get the integer value as a constant.
21327 
21328   llvm::APSInt ConstLength = Result.Val.getInt();
21329   return ConstLength.getSExtValue() != 1;
21330 }
21331 
21332 // The base of elements of list in a map clause have to be either:
21333 //  - a reference to variable or field.
21334 //  - a member expression.
21335 //  - an array expression.
21336 //
21337 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
21338 // reference to 'r'.
21339 //
21340 // If we have:
21341 //
21342 // struct SS {
21343 //   Bla S;
21344 //   foo() {
21345 //     #pragma omp target map (S.Arr[:12]);
21346 //   }
21347 // }
21348 //
21349 // We want to retrieve the member expression 'this->S';
21350 
21351 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
21352 //  If a list item is an array section, it must specify contiguous storage.
21353 //
21354 // For this restriction it is sufficient that we make sure only references
21355 // to variables or fields and array expressions, and that no array sections
21356 // exist except in the rightmost expression (unless they cover the whole
21357 // dimension of the array). E.g. these would be invalid:
21358 //
21359 //   r.ArrS[3:5].Arr[6:7]
21360 //
21361 //   r.ArrS[3:5].x
21362 //
21363 // but these would be valid:
21364 //   r.ArrS[3].Arr[6:7]
21365 //
21366 //   r.ArrS[3].x
21367 namespace {
21368 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
21369   Sema &SemaRef;
21370   OpenMPClauseKind CKind = OMPC_unknown;
21371   OpenMPDirectiveKind DKind = OMPD_unknown;
21372   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
21373   bool IsNonContiguous = false;
21374   bool NoDiagnose = false;
21375   const Expr *RelevantExpr = nullptr;
21376   bool AllowUnitySizeArraySection = true;
21377   bool AllowWholeSizeArraySection = true;
21378   bool AllowAnotherPtr = true;
21379   SourceLocation ELoc;
21380   SourceRange ERange;
21381 
emitErrorMsg()21382   void emitErrorMsg() {
21383     // If nothing else worked, this is not a valid map clause expression.
21384     if (SemaRef.getLangOpts().OpenMP < 50) {
21385       SemaRef.Diag(ELoc,
21386                    diag::err_omp_expected_named_var_member_or_array_expression)
21387           << ERange;
21388     } else {
21389       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21390           << getOpenMPClauseName(CKind) << ERange;
21391     }
21392   }
21393 
21394 public:
VisitDeclRefExpr(DeclRefExpr * DRE)21395   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
21396     if (!isa<VarDecl>(DRE->getDecl())) {
21397       emitErrorMsg();
21398       return false;
21399     }
21400     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21401     RelevantExpr = DRE;
21402     // Record the component.
21403     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
21404     return true;
21405   }
21406 
VisitMemberExpr(MemberExpr * ME)21407   bool VisitMemberExpr(MemberExpr *ME) {
21408     Expr *E = ME;
21409     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
21410 
21411     if (isa<CXXThisExpr>(BaseE)) {
21412       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21413       // We found a base expression: this->Val.
21414       RelevantExpr = ME;
21415     } else {
21416       E = BaseE;
21417     }
21418 
21419     if (!isa<FieldDecl>(ME->getMemberDecl())) {
21420       if (!NoDiagnose) {
21421         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21422             << ME->getSourceRange();
21423         return false;
21424       }
21425       if (RelevantExpr)
21426         return false;
21427       return Visit(E);
21428     }
21429 
21430     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
21431 
21432     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
21433     //  A bit-field cannot appear in a map clause.
21434     //
21435     if (FD->isBitField()) {
21436       if (!NoDiagnose) {
21437         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21438             << ME->getSourceRange() << getOpenMPClauseName(CKind);
21439         return false;
21440       }
21441       if (RelevantExpr)
21442         return false;
21443       return Visit(E);
21444     }
21445 
21446     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21447     //  If the type of a list item is a reference to a type T then the type
21448     //  will be considered to be T for all purposes of this clause.
21449     QualType CurType = BaseE->getType().getNonReferenceType();
21450 
21451     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
21452     //  A list item cannot be a variable that is a member of a structure with
21453     //  a union type.
21454     //
21455     if (CurType->isUnionType()) {
21456       if (!NoDiagnose) {
21457         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21458             << ME->getSourceRange();
21459         return false;
21460       }
21461       return RelevantExpr || Visit(E);
21462     }
21463 
21464     // If we got a member expression, we should not expect any array section
21465     // before that:
21466     //
21467     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
21468     //  If a list item is an element of a structure, only the rightmost symbol
21469     //  of the variable reference can be an array section.
21470     //
21471     AllowUnitySizeArraySection = false;
21472     AllowWholeSizeArraySection = false;
21473 
21474     // Record the component.
21475     Components.emplace_back(ME, FD, IsNonContiguous);
21476     return RelevantExpr || Visit(E);
21477   }
21478 
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)21479   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
21480     Expr *E = AE->getBase()->IgnoreParenImpCasts();
21481 
21482     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
21483       if (!NoDiagnose) {
21484         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21485             << 0 << AE->getSourceRange();
21486         return false;
21487       }
21488       return RelevantExpr || Visit(E);
21489     }
21490 
21491     // If we got an array subscript that express the whole dimension we
21492     // can have any array expressions before. If it only expressing part of
21493     // the dimension, we can only have unitary-size array expressions.
21494     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
21495       AllowWholeSizeArraySection = false;
21496 
21497     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21498       Expr::EvalResult Result;
21499       if (!AE->getIdx()->isValueDependent() &&
21500           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21501           !Result.Val.getInt().isZero()) {
21502         SemaRef.Diag(AE->getIdx()->getExprLoc(),
21503                      diag::err_omp_invalid_map_this_expr);
21504         SemaRef.Diag(AE->getIdx()->getExprLoc(),
21505                      diag::note_omp_invalid_subscript_on_this_ptr_map);
21506       }
21507       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21508       RelevantExpr = TE;
21509     }
21510 
21511     // Record the component - we don't have any declaration associated.
21512     Components.emplace_back(AE, nullptr, IsNonContiguous);
21513 
21514     return RelevantExpr || Visit(E);
21515   }
21516 
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)21517   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21518     // After OMP 5.0  Array section in reduction clause will be implicitly
21519     // mapped
21520     assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21521            "Array sections cannot be implicitly mapped.");
21522     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21523     QualType CurType =
21524         OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21525 
21526     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21527     //  If the type of a list item is a reference to a type T then the type
21528     //  will be considered to be T for all purposes of this clause.
21529     if (CurType->isReferenceType())
21530       CurType = CurType->getPointeeType();
21531 
21532     bool IsPointer = CurType->isAnyPointerType();
21533 
21534     if (!IsPointer && !CurType->isArrayType()) {
21535       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21536           << 0 << OASE->getSourceRange();
21537       return false;
21538     }
21539 
21540     bool NotWhole =
21541         checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21542     bool NotUnity =
21543         checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21544 
21545     if (AllowWholeSizeArraySection) {
21546       // Any array section is currently allowed. Allowing a whole size array
21547       // section implies allowing a unity array section as well.
21548       //
21549       // If this array section refers to the whole dimension we can still
21550       // accept other array sections before this one, except if the base is a
21551       // pointer. Otherwise, only unitary sections are accepted.
21552       if (NotWhole || IsPointer)
21553         AllowWholeSizeArraySection = false;
21554     } else if (DKind == OMPD_target_update &&
21555                SemaRef.getLangOpts().OpenMP >= 50) {
21556       if (IsPointer && !AllowAnotherPtr)
21557         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21558             << /*array of unknown bound */ 1;
21559       else
21560         IsNonContiguous = true;
21561     } else if (AllowUnitySizeArraySection && NotUnity) {
21562       // A unity or whole array section is not allowed and that is not
21563       // compatible with the properties of the current array section.
21564       if (NoDiagnose)
21565         return false;
21566       SemaRef.Diag(ELoc,
21567                    diag::err_array_section_does_not_specify_contiguous_storage)
21568           << OASE->getSourceRange();
21569       return false;
21570     }
21571 
21572     if (IsPointer)
21573       AllowAnotherPtr = false;
21574 
21575     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21576       Expr::EvalResult ResultR;
21577       Expr::EvalResult ResultL;
21578       if (!OASE->getLength()->isValueDependent() &&
21579           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21580           !ResultR.Val.getInt().isOne()) {
21581         SemaRef.Diag(OASE->getLength()->getExprLoc(),
21582                      diag::err_omp_invalid_map_this_expr);
21583         SemaRef.Diag(OASE->getLength()->getExprLoc(),
21584                      diag::note_omp_invalid_length_on_this_ptr_mapping);
21585       }
21586       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
21587           OASE->getLowerBound()->EvaluateAsInt(ResultL,
21588                                                SemaRef.getASTContext()) &&
21589           !ResultL.Val.getInt().isZero()) {
21590         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21591                      diag::err_omp_invalid_map_this_expr);
21592         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21593                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21594       }
21595       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21596       RelevantExpr = TE;
21597     }
21598 
21599     // Record the component - we don't have any declaration associated.
21600     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21601     return RelevantExpr || Visit(E);
21602   }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)21603   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21604     Expr *Base = E->getBase();
21605 
21606     // Record the component - we don't have any declaration associated.
21607     Components.emplace_back(E, nullptr, IsNonContiguous);
21608 
21609     return Visit(Base->IgnoreParenImpCasts());
21610   }
21611 
VisitUnaryOperator(UnaryOperator * UO)21612   bool VisitUnaryOperator(UnaryOperator *UO) {
21613     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
21614         UO->getOpcode() != UO_Deref) {
21615       emitErrorMsg();
21616       return false;
21617     }
21618     if (!RelevantExpr) {
21619       // Record the component if haven't found base decl.
21620       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21621     }
21622     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21623   }
VisitBinaryOperator(BinaryOperator * BO)21624   bool VisitBinaryOperator(BinaryOperator *BO) {
21625     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
21626       emitErrorMsg();
21627       return false;
21628     }
21629 
21630     // Pointer arithmetic is the only thing we expect to happen here so after we
21631     // make sure the binary operator is a pointer type, the only thing we need
21632     // to do is to visit the subtree that has the same type as root (so that we
21633     // know the other subtree is just an offset)
21634     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21635     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21636     Components.emplace_back(BO, nullptr, false);
21637     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
21638             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
21639            "Either LHS or RHS have base decl inside");
21640     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21641       return RelevantExpr || Visit(LE);
21642     return RelevantExpr || Visit(RE);
21643   }
VisitCXXThisExpr(CXXThisExpr * CTE)21644   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21645     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21646     RelevantExpr = CTE;
21647     Components.emplace_back(CTE, nullptr, IsNonContiguous);
21648     return true;
21649   }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)21650   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21651     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21652     Components.emplace_back(COCE, nullptr, IsNonContiguous);
21653     return true;
21654   }
VisitOpaqueValueExpr(OpaqueValueExpr * E)21655   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21656     Expr *Source = E->getSourceExpr();
21657     if (!Source) {
21658       emitErrorMsg();
21659       return false;
21660     }
21661     return Visit(Source);
21662   }
VisitStmt(Stmt *)21663   bool VisitStmt(Stmt *) {
21664     emitErrorMsg();
21665     return false;
21666   }
getFoundBase() const21667   const Expr *getFoundBase() const { return RelevantExpr; }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)21668   explicit MapBaseChecker(
21669       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21670       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
21671       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21672       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21673         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21674 };
21675 } // namespace
21676 
21677 /// Return the expression of the base of the mappable expression or null if it
21678 /// cannot be determined and do all the necessary checks to see if the
21679 /// expression is valid as a standalone mappable expression. In the process,
21680 /// record all the components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)21681 static const Expr *checkMapClauseExpressionBase(
21682     Sema &SemaRef, Expr *E,
21683     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
21684     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21685   SourceLocation ELoc = E->getExprLoc();
21686   SourceRange ERange = E->getSourceRange();
21687   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21688                          ERange);
21689   if (Checker.Visit(E->IgnoreParens())) {
21690     // Check if the highest dimension array section has length specified
21691     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21692         (CKind == OMPC_to || CKind == OMPC_from)) {
21693       auto CI = CurComponents.rbegin();
21694       auto CE = CurComponents.rend();
21695       for (; CI != CE; ++CI) {
21696         const auto *OASE =
21697             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21698         if (!OASE)
21699           continue;
21700         if (OASE && OASE->getLength())
21701           break;
21702         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21703             << ERange;
21704       }
21705     }
21706     return Checker.getFoundBase();
21707   }
21708   return nullptr;
21709 }
21710 
21711 // Return true if expression E associated with value VD has conflicts with other
21712 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)21713 static bool checkMapConflicts(
21714     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21715     bool CurrentRegionOnly,
21716     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21717     OpenMPClauseKind CKind) {
21718   assert(VD && E);
21719   SourceLocation ELoc = E->getExprLoc();
21720   SourceRange ERange = E->getSourceRange();
21721 
21722   // In order to easily check the conflicts we need to match each component of
21723   // the expression under test with the components of the expressions that are
21724   // already in the stack.
21725 
21726   assert(!CurComponents.empty() && "Map clause expression with no components!");
21727   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21728          "Map clause expression with unexpected base!");
21729 
21730   // Variables to help detecting enclosing problems in data environment nests.
21731   bool IsEnclosedByDataEnvironmentExpr = false;
21732   const Expr *EnclosingExpr = nullptr;
21733 
21734   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21735       VD, CurrentRegionOnly,
21736       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21737        ERange, CKind, &EnclosingExpr,
21738        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21739                           StackComponents,
21740                       OpenMPClauseKind Kind) {
21741         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21742           return false;
21743         assert(!StackComponents.empty() &&
21744                "Map clause expression with no components!");
21745         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21746                "Map clause expression with unexpected base!");
21747         (void)VD;
21748 
21749         // The whole expression in the stack.
21750         const Expr *RE = StackComponents.front().getAssociatedExpression();
21751 
21752         // Expressions must start from the same base. Here we detect at which
21753         // point both expressions diverge from each other and see if we can
21754         // detect if the memory referred to both expressions is contiguous and
21755         // do not overlap.
21756         auto CI = CurComponents.rbegin();
21757         auto CE = CurComponents.rend();
21758         auto SI = StackComponents.rbegin();
21759         auto SE = StackComponents.rend();
21760         for (; CI != CE && SI != SE; ++CI, ++SI) {
21761 
21762           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21763           //  At most one list item can be an array item derived from a given
21764           //  variable in map clauses of the same construct.
21765           if (CurrentRegionOnly &&
21766               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21767                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21768                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21769               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21770                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21771                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21772             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21773                          diag::err_omp_multiple_array_items_in_map_clause)
21774                 << CI->getAssociatedExpression()->getSourceRange();
21775             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21776                          diag::note_used_here)
21777                 << SI->getAssociatedExpression()->getSourceRange();
21778             return true;
21779           }
21780 
21781           // Do both expressions have the same kind?
21782           if (CI->getAssociatedExpression()->getStmtClass() !=
21783               SI->getAssociatedExpression()->getStmtClass())
21784             break;
21785 
21786           // Are we dealing with different variables/fields?
21787           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21788             break;
21789         }
21790         // Check if the extra components of the expressions in the enclosing
21791         // data environment are redundant for the current base declaration.
21792         // If they are, the maps completely overlap, which is legal.
21793         for (; SI != SE; ++SI) {
21794           QualType Type;
21795           if (const auto *ASE =
21796                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21797             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21798           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21799                          SI->getAssociatedExpression())) {
21800             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21801             Type =
21802                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21803           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21804                          SI->getAssociatedExpression())) {
21805             Type = OASE->getBase()->getType()->getPointeeType();
21806           }
21807           if (Type.isNull() || Type->isAnyPointerType() ||
21808               checkArrayExpressionDoesNotReferToWholeSize(
21809                   SemaRef, SI->getAssociatedExpression(), Type))
21810             break;
21811         }
21812 
21813         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21814         //  List items of map clauses in the same construct must not share
21815         //  original storage.
21816         //
21817         // If the expressions are exactly the same or one is a subset of the
21818         // other, it means they are sharing storage.
21819         if (CI == CE && SI == SE) {
21820           if (CurrentRegionOnly) {
21821             if (CKind == OMPC_map) {
21822               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21823             } else {
21824               assert(CKind == OMPC_to || CKind == OMPC_from);
21825               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21826                   << ERange;
21827             }
21828             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21829                 << RE->getSourceRange();
21830             return true;
21831           }
21832           // If we find the same expression in the enclosing data environment,
21833           // that is legal.
21834           IsEnclosedByDataEnvironmentExpr = true;
21835           return false;
21836         }
21837 
21838         QualType DerivedType =
21839             std::prev(CI)->getAssociatedDeclaration()->getType();
21840         SourceLocation DerivedLoc =
21841             std::prev(CI)->getAssociatedExpression()->getExprLoc();
21842 
21843         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21844         //  If the type of a list item is a reference to a type T then the type
21845         //  will be considered to be T for all purposes of this clause.
21846         DerivedType = DerivedType.getNonReferenceType();
21847 
21848         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21849         //  A variable for which the type is pointer and an array section
21850         //  derived from that variable must not appear as list items of map
21851         //  clauses of the same construct.
21852         //
21853         // Also, cover one of the cases in:
21854         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21855         //  If any part of the original storage of a list item has corresponding
21856         //  storage in the device data environment, all of the original storage
21857         //  must have corresponding storage in the device data environment.
21858         //
21859         if (DerivedType->isAnyPointerType()) {
21860           if (CI == CE || SI == SE) {
21861             SemaRef.Diag(
21862                 DerivedLoc,
21863                 diag::err_omp_pointer_mapped_along_with_derived_section)
21864                 << DerivedLoc;
21865             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21866                 << RE->getSourceRange();
21867             return true;
21868           }
21869           if (CI->getAssociatedExpression()->getStmtClass() !=
21870                   SI->getAssociatedExpression()->getStmtClass() ||
21871               CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21872                   SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21873             assert(CI != CE && SI != SE);
21874             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21875                 << DerivedLoc;
21876             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21877                 << RE->getSourceRange();
21878             return true;
21879           }
21880         }
21881 
21882         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21883         //  List items of map clauses in the same construct must not share
21884         //  original storage.
21885         //
21886         // An expression is a subset of the other.
21887         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21888           if (CKind == OMPC_map) {
21889             if (CI != CE || SI != SE) {
21890               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21891               // a pointer.
21892               auto Begin =
21893                   CI != CE ? CurComponents.begin() : StackComponents.begin();
21894               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21895               auto It = Begin;
21896               while (It != End && !It->getAssociatedDeclaration())
21897                 std::advance(It, 1);
21898               assert(It != End &&
21899                      "Expected at least one component with the declaration.");
21900               if (It != Begin && It->getAssociatedDeclaration()
21901                                      ->getType()
21902                                      .getCanonicalType()
21903                                      ->isAnyPointerType()) {
21904                 IsEnclosedByDataEnvironmentExpr = false;
21905                 EnclosingExpr = nullptr;
21906                 return false;
21907               }
21908             }
21909             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21910           } else {
21911             assert(CKind == OMPC_to || CKind == OMPC_from);
21912             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21913                 << ERange;
21914           }
21915           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21916               << RE->getSourceRange();
21917           return true;
21918         }
21919 
21920         // The current expression uses the same base as other expression in the
21921         // data environment but does not contain it completely.
21922         if (!CurrentRegionOnly && SI != SE)
21923           EnclosingExpr = RE;
21924 
21925         // The current expression is a subset of the expression in the data
21926         // environment.
21927         IsEnclosedByDataEnvironmentExpr |=
21928             (!CurrentRegionOnly && CI != CE && SI == SE);
21929 
21930         return false;
21931       });
21932 
21933   if (CurrentRegionOnly)
21934     return FoundError;
21935 
21936   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21937   //  If any part of the original storage of a list item has corresponding
21938   //  storage in the device data environment, all of the original storage must
21939   //  have corresponding storage in the device data environment.
21940   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21941   //  If a list item is an element of a structure, and a different element of
21942   //  the structure has a corresponding list item in the device data environment
21943   //  prior to a task encountering the construct associated with the map clause,
21944   //  then the list item must also have a corresponding list item in the device
21945   //  data environment prior to the task encountering the construct.
21946   //
21947   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21948     SemaRef.Diag(ELoc,
21949                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
21950         << ERange;
21951     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21952         << EnclosingExpr->getSourceRange();
21953     return true;
21954   }
21955 
21956   return FoundError;
21957 }
21958 
21959 // Look up the user-defined mapper given the mapper name and mapped type, and
21960 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)21961 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21962                                             CXXScopeSpec &MapperIdScopeSpec,
21963                                             const DeclarationNameInfo &MapperId,
21964                                             QualType Type,
21965                                             Expr *UnresolvedMapper) {
21966   if (MapperIdScopeSpec.isInvalid())
21967     return ExprError();
21968   // Get the actual type for the array type.
21969   if (Type->isArrayType()) {
21970     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21971     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21972   }
21973   // Find all user-defined mappers with the given MapperId.
21974   SmallVector<UnresolvedSet<8>, 4> Lookups;
21975   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21976   Lookup.suppressDiagnostics();
21977   if (S) {
21978     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21979       NamedDecl *D = Lookup.getRepresentativeDecl();
21980       while (S && !S->isDeclScope(D))
21981         S = S->getParent();
21982       if (S)
21983         S = S->getParent();
21984       Lookups.emplace_back();
21985       Lookups.back().append(Lookup.begin(), Lookup.end());
21986       Lookup.clear();
21987     }
21988   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21989     // Extract the user-defined mappers with the given MapperId.
21990     Lookups.push_back(UnresolvedSet<8>());
21991     for (NamedDecl *D : ULE->decls()) {
21992       auto *DMD = cast<OMPDeclareMapperDecl>(D);
21993       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21994       Lookups.back().addDecl(DMD);
21995     }
21996   }
21997   // Defer the lookup for dependent types. The results will be passed through
21998   // UnresolvedMapper on instantiation.
21999   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
22000       Type->isInstantiationDependentType() ||
22001       Type->containsUnexpandedParameterPack() ||
22002       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
22003         return !D->isInvalidDecl() &&
22004                (D->getType()->isDependentType() ||
22005                 D->getType()->isInstantiationDependentType() ||
22006                 D->getType()->containsUnexpandedParameterPack());
22007       })) {
22008     UnresolvedSet<8> URS;
22009     for (const UnresolvedSet<8> &Set : Lookups) {
22010       if (Set.empty())
22011         continue;
22012       URS.append(Set.begin(), Set.end());
22013     }
22014     return UnresolvedLookupExpr::Create(
22015         SemaRef.Context, /*NamingClass=*/nullptr,
22016         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
22017         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
22018   }
22019   SourceLocation Loc = MapperId.getLoc();
22020   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22021   //  The type must be of struct, union or class type in C and C++
22022   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
22023       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
22024     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
22025     return ExprError();
22026   }
22027   // Perform argument dependent lookup.
22028   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
22029     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
22030   // Return the first user-defined mapper with the desired type.
22031   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22032           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
22033             if (!D->isInvalidDecl() &&
22034                 SemaRef.Context.hasSameType(D->getType(), Type))
22035               return D;
22036             return nullptr;
22037           }))
22038     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
22039   // Find the first user-defined mapper with a type derived from the desired
22040   // type.
22041   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22042           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
22043             if (!D->isInvalidDecl() &&
22044                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
22045                 !Type.isMoreQualifiedThan(D->getType()))
22046               return D;
22047             return nullptr;
22048           })) {
22049     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
22050                        /*DetectVirtual=*/false);
22051     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
22052       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
22053               VD->getType().getUnqualifiedType()))) {
22054         if (SemaRef.CheckBaseClassAccess(
22055                 Loc, VD->getType(), Type, Paths.front(),
22056                 /*DiagID=*/0) != Sema::AR_inaccessible) {
22057           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
22058         }
22059       }
22060     }
22061   }
22062   // Report error if a mapper is specified, but cannot be found.
22063   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
22064     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
22065         << Type << MapperId.getName();
22066     return ExprError();
22067   }
22068   return ExprEmpty();
22069 }
22070 
22071 namespace {
22072 // Utility struct that gathers all the related lists associated with a mappable
22073 // expression.
22074 struct MappableVarListInfo {
22075   // The list of expressions.
22076   ArrayRef<Expr *> VarList;
22077   // The list of processed expressions.
22078   SmallVector<Expr *, 16> ProcessedVarList;
22079   // The mappble components for each expression.
22080   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
22081   // The base declaration of the variable.
22082   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
22083   // The reference to the user-defined mapper associated with every expression.
22084   SmallVector<Expr *, 16> UDMapperList;
22085 
MappableVarListInfo__anon61cef30c6611::MappableVarListInfo22086   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
22087     // We have a list of components and base declarations for each entry in the
22088     // variable list.
22089     VarComponents.reserve(VarList.size());
22090     VarBaseDeclarations.reserve(VarList.size());
22091   }
22092 };
22093 } // namespace
22094 
22095 // Check the validity of the provided variable list for the provided clause kind
22096 // \a CKind. In the check process the valid expressions, mappable expression
22097 // components, variables, and user-defined mappers are extracted and used to
22098 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
22099 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
22100 // 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=std::nullopt,bool IsMapTypeImplicit=false,bool NoDiagnose=false)22101 static void checkMappableExpressionList(
22102     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
22103     MappableVarListInfo &MVLI, SourceLocation StartLoc,
22104     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
22105     ArrayRef<Expr *> UnresolvedMappers,
22106     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
22107     ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
22108     bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
22109   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
22110   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22111          "Unexpected clause kind with mappable expressions!");
22112 
22113   // If the identifier of user-defined mapper is not specified, it is "default".
22114   // We do not change the actual name in this clause to distinguish whether a
22115   // mapper is specified explicitly, i.e., it is not explicitly specified when
22116   // MapperId.getName() is empty.
22117   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
22118     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
22119     MapperId.setName(DeclNames.getIdentifier(
22120         &SemaRef.getASTContext().Idents.get("default")));
22121     MapperId.setLoc(StartLoc);
22122   }
22123 
22124   // Iterators to find the current unresolved mapper expression.
22125   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22126   bool UpdateUMIt = false;
22127   Expr *UnresolvedMapper = nullptr;
22128 
22129   bool HasHoldModifier =
22130       llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22131 
22132   // Keep track of the mappable components and base declarations in this clause.
22133   // Each entry in the list is going to have a list of components associated. We
22134   // record each set of the components so that we can build the clause later on.
22135   // In the end we should have the same amount of declarations and component
22136   // lists.
22137 
22138   for (Expr *RE : MVLI.VarList) {
22139     assert(RE && "Null expr in omp to/from/map clause");
22140     SourceLocation ELoc = RE->getExprLoc();
22141 
22142     // Find the current unresolved mapper expression.
22143     if (UpdateUMIt && UMIt != UMEnd) {
22144       UMIt++;
22145       assert(
22146           UMIt != UMEnd &&
22147           "Expect the size of UnresolvedMappers to match with that of VarList");
22148     }
22149     UpdateUMIt = true;
22150     if (UMIt != UMEnd)
22151       UnresolvedMapper = *UMIt;
22152 
22153     const Expr *VE = RE->IgnoreParenLValueCasts();
22154 
22155     if (VE->isValueDependent() || VE->isTypeDependent() ||
22156         VE->isInstantiationDependent() ||
22157         VE->containsUnexpandedParameterPack()) {
22158       // Try to find the associated user-defined mapper.
22159       ExprResult ER = buildUserDefinedMapperRef(
22160           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22161           VE->getType().getCanonicalType(), UnresolvedMapper);
22162       if (ER.isInvalid())
22163         continue;
22164       MVLI.UDMapperList.push_back(ER.get());
22165       // We can only analyze this information once the missing information is
22166       // resolved.
22167       MVLI.ProcessedVarList.push_back(RE);
22168       continue;
22169     }
22170 
22171     Expr *SimpleExpr = RE->IgnoreParenCasts();
22172 
22173     if (!RE->isLValue()) {
22174       if (SemaRef.getLangOpts().OpenMP < 50) {
22175         SemaRef.Diag(
22176             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22177             << RE->getSourceRange();
22178       } else {
22179         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22180             << getOpenMPClauseName(CKind) << RE->getSourceRange();
22181       }
22182       continue;
22183     }
22184 
22185     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
22186     ValueDecl *CurDeclaration = nullptr;
22187 
22188     // Obtain the array or member expression bases if required. Also, fill the
22189     // components array with all the components identified in the process.
22190     const Expr *BE =
22191         checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
22192                                      DSAS->getCurrentDirective(), NoDiagnose);
22193     if (!BE)
22194       continue;
22195 
22196     assert(!CurComponents.empty() &&
22197            "Invalid mappable expression information.");
22198 
22199     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22200       // Add store "this" pointer to class in DSAStackTy for future checking
22201       DSAS->addMappedClassesQualTypes(TE->getType());
22202       // Try to find the associated user-defined mapper.
22203       ExprResult ER = buildUserDefinedMapperRef(
22204           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22205           VE->getType().getCanonicalType(), UnresolvedMapper);
22206       if (ER.isInvalid())
22207         continue;
22208       MVLI.UDMapperList.push_back(ER.get());
22209       // Skip restriction checking for variable or field declarations
22210       MVLI.ProcessedVarList.push_back(RE);
22211       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22212       MVLI.VarComponents.back().append(CurComponents.begin(),
22213                                        CurComponents.end());
22214       MVLI.VarBaseDeclarations.push_back(nullptr);
22215       continue;
22216     }
22217 
22218     // For the following checks, we rely on the base declaration which is
22219     // expected to be associated with the last component. The declaration is
22220     // expected to be a variable or a field (if 'this' is being mapped).
22221     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22222     assert(CurDeclaration && "Null decl on map clause.");
22223     assert(
22224         CurDeclaration->isCanonicalDecl() &&
22225         "Expecting components to have associated only canonical declarations.");
22226 
22227     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22228     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22229 
22230     assert((VD || FD) && "Only variables or fields are expected here!");
22231     (void)FD;
22232 
22233     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
22234     // threadprivate variables cannot appear in a map clause.
22235     // OpenMP 4.5 [2.10.5, target update Construct]
22236     // threadprivate variables cannot appear in a from clause.
22237     if (VD && DSAS->isThreadPrivate(VD)) {
22238       if (NoDiagnose)
22239         continue;
22240       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22241       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22242           << getOpenMPClauseName(CKind);
22243       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
22244       continue;
22245     }
22246 
22247     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22248     //  A list item cannot appear in both a map clause and a data-sharing
22249     //  attribute clause on the same construct.
22250 
22251     // Check conflicts with other map clause expressions. We check the conflicts
22252     // with the current construct separately from the enclosing data
22253     // environment, because the restrictions are different. We only have to
22254     // check conflicts across regions for the map clauses.
22255     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22256                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
22257       break;
22258     if (CKind == OMPC_map &&
22259         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
22260         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22261                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
22262       break;
22263 
22264     // OpenMP 4.5 [2.10.5, target update Construct]
22265     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
22266     //  If the type of a list item is a reference to a type T then the type will
22267     //  be considered to be T for all purposes of this clause.
22268     auto I = llvm::find_if(
22269         CurComponents,
22270         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
22271           return MC.getAssociatedDeclaration();
22272         });
22273     assert(I != CurComponents.end() && "Null decl on map clause.");
22274     (void)I;
22275     QualType Type;
22276     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
22277     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
22278     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
22279     if (ASE) {
22280       Type = ASE->getType().getNonReferenceType();
22281     } else if (OASE) {
22282       QualType BaseType =
22283           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
22284       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
22285         Type = ATy->getElementType();
22286       else
22287         Type = BaseType->getPointeeType();
22288       Type = Type.getNonReferenceType();
22289     } else if (OAShE) {
22290       Type = OAShE->getBase()->getType()->getPointeeType();
22291     } else {
22292       Type = VE->getType();
22293     }
22294 
22295     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
22296     // A list item in a to or from clause must have a mappable type.
22297     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22298     //  A list item must have a mappable type.
22299     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
22300                            DSAS, Type, /*FullCheck=*/true))
22301       continue;
22302 
22303     if (CKind == OMPC_map) {
22304       // target enter data
22305       // OpenMP [2.10.2, Restrictions, p. 99]
22306       // A map-type must be specified in all map clauses and must be either
22307       // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
22308       // no map type is present.
22309       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
22310       if (DKind == OMPD_target_enter_data &&
22311           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22312             SemaRef.getLangOpts().OpenMP >= 52)) {
22313         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22314             << (IsMapTypeImplicit ? 1 : 0)
22315             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22316             << getOpenMPDirectiveName(DKind);
22317         continue;
22318       }
22319 
22320       // target exit_data
22321       // OpenMP [2.10.3, Restrictions, p. 102]
22322       // A map-type must be specified in all map clauses and must be either
22323       // from, release, or delete. Starting with OpenMP 5.2 the default map
22324       // type is `from` if no map type is present.
22325       if (DKind == OMPD_target_exit_data &&
22326           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22327             MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
22328         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22329             << (IsMapTypeImplicit ? 1 : 0)
22330             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22331             << getOpenMPDirectiveName(DKind);
22332         continue;
22333       }
22334 
22335       // The 'ompx_hold' modifier is specifically intended to be used on a
22336       // 'target' or 'target data' directive to prevent data from being unmapped
22337       // during the associated statement.  It is not permitted on a 'target
22338       // enter data' or 'target exit data' directive, which have no associated
22339       // statement.
22340       if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22341           HasHoldModifier) {
22342         SemaRef.Diag(StartLoc,
22343                      diag::err_omp_invalid_map_type_modifier_for_directive)
22344             << getOpenMPSimpleClauseTypeName(OMPC_map,
22345                                              OMPC_MAP_MODIFIER_ompx_hold)
22346             << getOpenMPDirectiveName(DKind);
22347         continue;
22348       }
22349 
22350       // target, target data
22351       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
22352       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
22353       // A map-type in a map clause must be to, from, tofrom or alloc
22354       if ((DKind == OMPD_target_data ||
22355            isOpenMPTargetExecutionDirective(DKind)) &&
22356           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22357             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22358         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22359             << (IsMapTypeImplicit ? 1 : 0)
22360             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22361             << getOpenMPDirectiveName(DKind);
22362         continue;
22363       }
22364 
22365       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
22366       // A list item cannot appear in both a map clause and a data-sharing
22367       // attribute clause on the same construct
22368       //
22369       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
22370       // A list item cannot appear in both a map clause and a data-sharing
22371       // attribute clause on the same construct unless the construct is a
22372       // combined construct.
22373       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
22374                   isOpenMPTargetExecutionDirective(DKind)) ||
22375                  DKind == OMPD_target)) {
22376         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22377         if (isOpenMPPrivate(DVar.CKind)) {
22378           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22379               << getOpenMPClauseName(DVar.CKind)
22380               << getOpenMPClauseName(OMPC_map)
22381               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22382           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
22383           continue;
22384         }
22385       }
22386     }
22387 
22388     // Try to find the associated user-defined mapper.
22389     ExprResult ER = buildUserDefinedMapperRef(
22390         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22391         Type.getCanonicalType(), UnresolvedMapper);
22392     if (ER.isInvalid())
22393       continue;
22394     MVLI.UDMapperList.push_back(ER.get());
22395 
22396     // Save the current expression.
22397     MVLI.ProcessedVarList.push_back(RE);
22398 
22399     // Store the components in the stack so that they can be used to check
22400     // against other clauses later on.
22401     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22402                                           /*WhereFoundClauseKind=*/OMPC_map);
22403 
22404     // Save the components and declaration to create the clause. For purposes of
22405     // the clause creation, any component list that has base 'this' uses
22406     // null as base declaration.
22407     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22408     MVLI.VarComponents.back().append(CurComponents.begin(),
22409                                      CurComponents.end());
22410     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
22411                                                            : CurDeclaration);
22412   }
22413 }
22414 
ActOnOpenMPMapClause(Expr * IteratorModifier,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)22415 OMPClause *Sema::ActOnOpenMPMapClause(
22416     Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
22417     ArrayRef<SourceLocation> MapTypeModifiersLoc,
22418     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22419     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
22420     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22421     const OMPVarListLocTy &Locs, bool NoDiagnose,
22422     ArrayRef<Expr *> UnresolvedMappers) {
22423   OpenMPMapModifierKind Modifiers[] = {
22424       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22425       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22426       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
22427   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
22428 
22429   if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
22430                               BuiltinType::OMPIterator))
22431     Diag(IteratorModifier->getExprLoc(),
22432          diag::err_omp_map_modifier_not_iterator);
22433 
22434   // Process map-type-modifiers, flag errors for duplicate modifiers.
22435   unsigned Count = 0;
22436   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22437     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
22438         llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22439       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22440       continue;
22441     }
22442     assert(Count < NumberOfOMPMapClauseModifiers &&
22443            "Modifiers exceed the allowed number of map type modifiers");
22444     Modifiers[Count] = MapTypeModifiers[I];
22445     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22446     ++Count;
22447   }
22448 
22449   MappableVarListInfo MVLI(VarList);
22450   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
22451                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
22452                               MapType, Modifiers, IsMapTypeImplicit,
22453                               NoDiagnose);
22454 
22455   // We need to produce a map clause even if we don't have variables so that
22456   // other diagnostics related with non-existing map clauses are accurate.
22457   return OMPMapClause::Create(
22458       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22459       MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22460       ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
22461       MapType, IsMapTypeImplicit, MapLoc);
22462 }
22463 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)22464 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
22465                                                TypeResult ParsedType) {
22466   assert(ParsedType.isUsable());
22467 
22468   QualType ReductionType = GetTypeFromParser(ParsedType.get());
22469   if (ReductionType.isNull())
22470     return QualType();
22471 
22472   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
22473   // A type name in a declare reduction directive cannot be a function type, an
22474   // array type, a reference type, or a type qualified with const, volatile or
22475   // restrict.
22476   if (ReductionType.hasQualifiers()) {
22477     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22478     return QualType();
22479   }
22480 
22481   if (ReductionType->isFunctionType()) {
22482     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22483     return QualType();
22484   }
22485   if (ReductionType->isReferenceType()) {
22486     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22487     return QualType();
22488   }
22489   if (ReductionType->isArrayType()) {
22490     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22491     return QualType();
22492   }
22493   return ReductionType;
22494 }
22495 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)22496 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
22497     Scope *S, DeclContext *DC, DeclarationName Name,
22498     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22499     AccessSpecifier AS, Decl *PrevDeclInScope) {
22500   SmallVector<Decl *, 8> Decls;
22501   Decls.reserve(ReductionTypes.size());
22502 
22503   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22504                       forRedeclarationInCurContext());
22505   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22506   // A reduction-identifier may not be re-declared in the current scope for the
22507   // same type or for a type that is compatible according to the base language
22508   // rules.
22509   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22510   OMPDeclareReductionDecl *PrevDRD = nullptr;
22511   bool InCompoundScope = true;
22512   if (S != nullptr) {
22513     // Find previous declaration with the same name not referenced in other
22514     // declarations.
22515     FunctionScopeInfo *ParentFn = getEnclosingFunction();
22516     InCompoundScope =
22517         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22518     LookupName(Lookup, S);
22519     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22520                          /*AllowInlineNamespace=*/false);
22521     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22522     LookupResult::Filter Filter = Lookup.makeFilter();
22523     while (Filter.hasNext()) {
22524       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22525       if (InCompoundScope) {
22526         auto I = UsedAsPrevious.find(PrevDecl);
22527         if (I == UsedAsPrevious.end())
22528           UsedAsPrevious[PrevDecl] = false;
22529         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22530           UsedAsPrevious[D] = true;
22531       }
22532       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22533           PrevDecl->getLocation();
22534     }
22535     Filter.done();
22536     if (InCompoundScope) {
22537       for (const auto &PrevData : UsedAsPrevious) {
22538         if (!PrevData.second) {
22539           PrevDRD = PrevData.first;
22540           break;
22541         }
22542       }
22543     }
22544   } else if (PrevDeclInScope != nullptr) {
22545     auto *PrevDRDInScope = PrevDRD =
22546         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22547     do {
22548       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22549           PrevDRDInScope->getLocation();
22550       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22551     } while (PrevDRDInScope != nullptr);
22552   }
22553   for (const auto &TyData : ReductionTypes) {
22554     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22555     bool Invalid = false;
22556     if (I != PreviousRedeclTypes.end()) {
22557       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22558           << TyData.first;
22559       Diag(I->second, diag::note_previous_definition);
22560       Invalid = true;
22561     }
22562     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22563     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22564                                                 Name, TyData.first, PrevDRD);
22565     DC->addDecl(DRD);
22566     DRD->setAccess(AS);
22567     Decls.push_back(DRD);
22568     if (Invalid)
22569       DRD->setInvalidDecl();
22570     else
22571       PrevDRD = DRD;
22572   }
22573 
22574   return DeclGroupPtrTy::make(
22575       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22576 }
22577 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)22578 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
22579   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22580 
22581   // Enter new function scope.
22582   PushFunctionScope();
22583   setFunctionHasBranchProtectedScope();
22584   getCurFunction()->setHasOMPDeclareReductionCombiner();
22585 
22586   if (S != nullptr)
22587     PushDeclContext(S, DRD);
22588   else
22589     CurContext = DRD;
22590 
22591   PushExpressionEvaluationContext(
22592       ExpressionEvaluationContext::PotentiallyEvaluated);
22593 
22594   QualType ReductionType = DRD->getType();
22595   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22596   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22597   // uses semantics of argument handles by value, but it should be passed by
22598   // reference. C lang does not support references, so pass all parameters as
22599   // pointers.
22600   // Create 'T omp_in;' variable.
22601   VarDecl *OmpInParm =
22602       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22603   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22604   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22605   // uses semantics of argument handles by value, but it should be passed by
22606   // reference. C lang does not support references, so pass all parameters as
22607   // pointers.
22608   // Create 'T omp_out;' variable.
22609   VarDecl *OmpOutParm =
22610       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22611   if (S != nullptr) {
22612     PushOnScopeChains(OmpInParm, S);
22613     PushOnScopeChains(OmpOutParm, S);
22614   } else {
22615     DRD->addDecl(OmpInParm);
22616     DRD->addDecl(OmpOutParm);
22617   }
22618   Expr *InE =
22619       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22620   Expr *OutE =
22621       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22622   DRD->setCombinerData(InE, OutE);
22623 }
22624 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)22625 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
22626   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22627   DiscardCleanupsInEvaluationContext();
22628   PopExpressionEvaluationContext();
22629 
22630   PopDeclContext();
22631   PopFunctionScopeInfo();
22632 
22633   if (Combiner != nullptr)
22634     DRD->setCombiner(Combiner);
22635   else
22636     DRD->setInvalidDecl();
22637 }
22638 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)22639 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
22640   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22641 
22642   // Enter new function scope.
22643   PushFunctionScope();
22644   setFunctionHasBranchProtectedScope();
22645 
22646   if (S != nullptr)
22647     PushDeclContext(S, DRD);
22648   else
22649     CurContext = DRD;
22650 
22651   PushExpressionEvaluationContext(
22652       ExpressionEvaluationContext::PotentiallyEvaluated);
22653 
22654   QualType ReductionType = DRD->getType();
22655   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22656   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22657   // uses semantics of argument handles by value, but it should be passed by
22658   // reference. C lang does not support references, so pass all parameters as
22659   // pointers.
22660   // Create 'T omp_priv;' variable.
22661   VarDecl *OmpPrivParm =
22662       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22663   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22664   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22665   // uses semantics of argument handles by value, but it should be passed by
22666   // reference. C lang does not support references, so pass all parameters as
22667   // pointers.
22668   // Create 'T omp_orig;' variable.
22669   VarDecl *OmpOrigParm =
22670       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22671   if (S != nullptr) {
22672     PushOnScopeChains(OmpPrivParm, S);
22673     PushOnScopeChains(OmpOrigParm, S);
22674   } else {
22675     DRD->addDecl(OmpPrivParm);
22676     DRD->addDecl(OmpOrigParm);
22677   }
22678   Expr *OrigE =
22679       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22680   Expr *PrivE =
22681       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22682   DRD->setInitializerData(OrigE, PrivE);
22683   return OmpPrivParm;
22684 }
22685 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)22686 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
22687                                                      VarDecl *OmpPrivParm) {
22688   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22689   DiscardCleanupsInEvaluationContext();
22690   PopExpressionEvaluationContext();
22691 
22692   PopDeclContext();
22693   PopFunctionScopeInfo();
22694 
22695   if (Initializer != nullptr) {
22696     DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call);
22697   } else if (OmpPrivParm->hasInit()) {
22698     DRD->setInitializer(OmpPrivParm->getInit(),
22699                         OmpPrivParm->isDirectInit()
22700                             ? OMPDeclareReductionInitKind::Direct
22701                             : OMPDeclareReductionInitKind::Copy);
22702   } else {
22703     DRD->setInvalidDecl();
22704   }
22705 }
22706 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)22707 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22708     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22709   for (Decl *D : DeclReductions.get()) {
22710     if (IsValid) {
22711       if (S)
22712         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22713                           /*AddToContext=*/false);
22714     } else {
22715       D->setInvalidDecl();
22716     }
22717   }
22718   return DeclReductions;
22719 }
22720 
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)22721 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22722   TypeSourceInfo *TInfo = GetTypeForDeclarator(D);
22723   QualType T = TInfo->getType();
22724   if (D.isInvalidType())
22725     return true;
22726 
22727   if (getLangOpts().CPlusPlus) {
22728     // Check that there are no default arguments (C++ only).
22729     CheckExtraCXXDefaultArguments(D);
22730   }
22731 
22732   return CreateParsedType(T, TInfo);
22733 }
22734 
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)22735 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22736                                             TypeResult ParsedType) {
22737   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22738 
22739   QualType MapperType = GetTypeFromParser(ParsedType.get());
22740   assert(!MapperType.isNull() && "Expect valid mapper type");
22741 
22742   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22743   //  The type must be of struct, union or class type in C and C++
22744   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22745     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22746     return QualType();
22747   }
22748   return MapperType;
22749 }
22750 
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)22751 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22752     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22753     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22754     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22755   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22756                       forRedeclarationInCurContext());
22757   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22758   //  A mapper-identifier may not be redeclared in the current scope for the
22759   //  same type or for a type that is compatible according to the base language
22760   //  rules.
22761   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22762   OMPDeclareMapperDecl *PrevDMD = nullptr;
22763   bool InCompoundScope = true;
22764   if (S != nullptr) {
22765     // Find previous declaration with the same name not referenced in other
22766     // declarations.
22767     FunctionScopeInfo *ParentFn = getEnclosingFunction();
22768     InCompoundScope =
22769         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22770     LookupName(Lookup, S);
22771     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22772                          /*AllowInlineNamespace=*/false);
22773     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22774     LookupResult::Filter Filter = Lookup.makeFilter();
22775     while (Filter.hasNext()) {
22776       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22777       if (InCompoundScope) {
22778         auto I = UsedAsPrevious.find(PrevDecl);
22779         if (I == UsedAsPrevious.end())
22780           UsedAsPrevious[PrevDecl] = false;
22781         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22782           UsedAsPrevious[D] = true;
22783       }
22784       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22785           PrevDecl->getLocation();
22786     }
22787     Filter.done();
22788     if (InCompoundScope) {
22789       for (const auto &PrevData : UsedAsPrevious) {
22790         if (!PrevData.second) {
22791           PrevDMD = PrevData.first;
22792           break;
22793         }
22794       }
22795     }
22796   } else if (PrevDeclInScope) {
22797     auto *PrevDMDInScope = PrevDMD =
22798         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22799     do {
22800       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22801           PrevDMDInScope->getLocation();
22802       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22803     } while (PrevDMDInScope != nullptr);
22804   }
22805   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22806   bool Invalid = false;
22807   if (I != PreviousRedeclTypes.end()) {
22808     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22809         << MapperType << Name;
22810     Diag(I->second, diag::note_previous_definition);
22811     Invalid = true;
22812   }
22813   // Build expressions for implicit maps of data members with 'default'
22814   // mappers.
22815   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22816                                                   Clauses.end());
22817   if (LangOpts.OpenMP >= 50)
22818     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22819   auto *DMD =
22820       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22821                                    ClausesWithImplicit, PrevDMD);
22822   if (S)
22823     PushOnScopeChains(DMD, S);
22824   else
22825     DC->addDecl(DMD);
22826   DMD->setAccess(AS);
22827   if (Invalid)
22828     DMD->setInvalidDecl();
22829 
22830   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22831   VD->setDeclContext(DMD);
22832   VD->setLexicalDeclContext(DMD);
22833   DMD->addDecl(VD);
22834   DMD->setMapperVarRef(MapperVarRef);
22835 
22836   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22837 }
22838 
22839 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)22840 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22841                                                SourceLocation StartLoc,
22842                                                DeclarationName VN) {
22843   TypeSourceInfo *TInfo =
22844       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22845   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22846                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22847                              MapperType, TInfo, SC_None);
22848   if (S)
22849     PushOnScopeChains(VD, S, /*AddToContext=*/false);
22850   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22851   DSAStack->addDeclareMapperVarRef(E);
22852   return E;
22853 }
22854 
ActOnOpenMPIteratorVarDecl(VarDecl * VD)22855 void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22856   if (DSAStack->getDeclareMapperVarRef())
22857     DSAStack->addIteratorVarDecl(VD);
22858 }
22859 
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const22860 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22861   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22862   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22863   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22864     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22865       return true;
22866     if (VD->isUsableInConstantExpressions(Context))
22867       return true;
22868     if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
22869       return true;
22870     return false;
22871   }
22872   return true;
22873 }
22874 
getOpenMPDeclareMapperVarName() const22875 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22876   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22877   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22878 }
22879 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22880 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22881                                            SourceLocation StartLoc,
22882                                            SourceLocation LParenLoc,
22883                                            SourceLocation EndLoc) {
22884   Expr *ValExpr = NumTeams;
22885   Stmt *HelperValStmt = nullptr;
22886 
22887   // OpenMP [teams Constrcut, Restrictions]
22888   // The num_teams expression must evaluate to a positive integer value.
22889   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22890                                  /*StrictlyPositive=*/true))
22891     return nullptr;
22892 
22893   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22894   OpenMPDirectiveKind CaptureRegion =
22895       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22896   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22897     ValExpr = MakeFullExpr(ValExpr).get();
22898     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22899     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22900     HelperValStmt = buildPreInits(Context, Captures);
22901   }
22902 
22903   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22904                                          StartLoc, LParenLoc, EndLoc);
22905 }
22906 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22907 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22908                                               SourceLocation StartLoc,
22909                                               SourceLocation LParenLoc,
22910                                               SourceLocation EndLoc) {
22911   Expr *ValExpr = ThreadLimit;
22912   Stmt *HelperValStmt = nullptr;
22913 
22914   // OpenMP [teams Constrcut, Restrictions]
22915   // The thread_limit expression must evaluate to a positive integer value.
22916   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22917                                  /*StrictlyPositive=*/true))
22918     return nullptr;
22919 
22920   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22921   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22922       DKind, OMPC_thread_limit, LangOpts.OpenMP);
22923   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22924     ValExpr = MakeFullExpr(ValExpr).get();
22925     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22926     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22927     HelperValStmt = buildPreInits(Context, Captures);
22928   }
22929 
22930   return new (Context) OMPThreadLimitClause(
22931       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22932 }
22933 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)22934 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22935                                            SourceLocation StartLoc,
22936                                            SourceLocation LParenLoc,
22937                                            SourceLocation EndLoc) {
22938   Expr *ValExpr = Priority;
22939   Stmt *HelperValStmt = nullptr;
22940   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22941 
22942   // OpenMP [2.9.1, task Constrcut]
22943   // The priority-value is a non-negative numerical scalar expression.
22944   if (!isNonNegativeIntegerValue(
22945           ValExpr, *this, OMPC_priority,
22946           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22947           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22948     return nullptr;
22949 
22950   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22951                                          StartLoc, LParenLoc, EndLoc);
22952 }
22953 
ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)22954 OMPClause *Sema::ActOnOpenMPGrainsizeClause(
22955     OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22956     SourceLocation StartLoc, SourceLocation LParenLoc,
22957     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22958   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22959          "Unexpected grainsize modifier in OpenMP < 51.");
22960 
22961   if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22962     std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22963                                                  OMPC_GRAINSIZE_unknown);
22964     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22965         << Values << getOpenMPClauseName(OMPC_grainsize);
22966     return nullptr;
22967   }
22968 
22969   Expr *ValExpr = Grainsize;
22970   Stmt *HelperValStmt = nullptr;
22971   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22972 
22973   // OpenMP [2.9.2, taskloop Constrcut]
22974   // The parameter of the grainsize clause must be a positive integer
22975   // expression.
22976   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22977                                  /*StrictlyPositive=*/true,
22978                                  /*BuildCapture=*/true,
22979                                  DSAStack->getCurrentDirective(),
22980                                  &CaptureRegion, &HelperValStmt))
22981     return nullptr;
22982 
22983   return new (Context)
22984       OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22985                          StartLoc, LParenLoc, ModifierLoc, EndLoc);
22986 }
22987 
ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)22988 OMPClause *Sema::ActOnOpenMPNumTasksClause(
22989     OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22990     SourceLocation StartLoc, SourceLocation LParenLoc,
22991     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22992   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22993          "Unexpected num_tasks modifier in OpenMP < 51.");
22994 
22995   if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22996     std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22997                                                  OMPC_NUMTASKS_unknown);
22998     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22999         << Values << getOpenMPClauseName(OMPC_num_tasks);
23000     return nullptr;
23001   }
23002 
23003   Expr *ValExpr = NumTasks;
23004   Stmt *HelperValStmt = nullptr;
23005   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
23006 
23007   // OpenMP [2.9.2, taskloop Constrcut]
23008   // The parameter of the num_tasks clause must be a positive integer
23009   // expression.
23010   if (!isNonNegativeIntegerValue(
23011           ValExpr, *this, OMPC_num_tasks,
23012           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
23013           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
23014     return nullptr;
23015 
23016   return new (Context)
23017       OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
23018                         StartLoc, LParenLoc, ModifierLoc, EndLoc);
23019 }
23020 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23021 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
23022                                        SourceLocation LParenLoc,
23023                                        SourceLocation EndLoc) {
23024   // OpenMP [2.13.2, critical construct, Description]
23025   // ... where hint-expression is an integer constant expression that evaluates
23026   // to a valid lock hint.
23027   ExprResult HintExpr =
23028       VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
23029   if (HintExpr.isInvalid())
23030     return nullptr;
23031   return new (Context)
23032       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
23033 }
23034 
23035 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)23036 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
23037                                 DSAStackTy *Stack) {
23038   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
23039   if (!OMPEventHandleT.isNull())
23040     return true;
23041   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
23042   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
23043   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23044     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
23045     return false;
23046   }
23047   Stack->setOMPEventHandleT(PT.get());
23048   return true;
23049 }
23050 
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23051 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
23052                                          SourceLocation LParenLoc,
23053                                          SourceLocation EndLoc) {
23054   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
23055       !Evt->isInstantiationDependent() &&
23056       !Evt->containsUnexpandedParameterPack()) {
23057     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
23058       return nullptr;
23059     // OpenMP 5.0, 2.10.1 task Construct.
23060     // event-handle is a variable of the omp_event_handle_t type.
23061     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
23062     if (!Ref) {
23063       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23064           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
23065       return nullptr;
23066     }
23067     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
23068     if (!VD) {
23069       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23070           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
23071       return nullptr;
23072     }
23073     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
23074                                         VD->getType()) ||
23075         VD->getType().isConstant(Context)) {
23076       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23077           << "omp_event_handle_t" << 1 << VD->getType()
23078           << Evt->getSourceRange();
23079       return nullptr;
23080     }
23081     // OpenMP 5.0, 2.10.1 task Construct
23082     // [detach clause]... The event-handle will be considered as if it was
23083     // specified on a firstprivate clause.
23084     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
23085     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
23086         DVar.RefExpr) {
23087       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
23088           << getOpenMPClauseName(DVar.CKind)
23089           << getOpenMPClauseName(OMPC_firstprivate);
23090       reportOriginalDsa(*this, DSAStack, VD, DVar);
23091       return nullptr;
23092     }
23093   }
23094 
23095   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
23096 }
23097 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)23098 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
23099     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
23100     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
23101     SourceLocation EndLoc) {
23102   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
23103     std::string Values;
23104     Values += "'";
23105     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
23106     Values += "'";
23107     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23108         << Values << getOpenMPClauseName(OMPC_dist_schedule);
23109     return nullptr;
23110   }
23111   Expr *ValExpr = ChunkSize;
23112   Stmt *HelperValStmt = nullptr;
23113   if (ChunkSize) {
23114     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
23115         !ChunkSize->isInstantiationDependent() &&
23116         !ChunkSize->containsUnexpandedParameterPack()) {
23117       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
23118       ExprResult Val =
23119           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
23120       if (Val.isInvalid())
23121         return nullptr;
23122 
23123       ValExpr = Val.get();
23124 
23125       // OpenMP [2.7.1, Restrictions]
23126       //  chunk_size must be a loop invariant integer expression with a positive
23127       //  value.
23128       if (std::optional<llvm::APSInt> Result =
23129               ValExpr->getIntegerConstantExpr(Context)) {
23130         if (Result->isSigned() && !Result->isStrictlyPositive()) {
23131           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23132               << "dist_schedule" << ChunkSize->getSourceRange();
23133           return nullptr;
23134         }
23135       } else if (getOpenMPCaptureRegionForClause(
23136                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23137                      LangOpts.OpenMP) != OMPD_unknown &&
23138                  !CurContext->isDependentContext()) {
23139         ValExpr = MakeFullExpr(ValExpr).get();
23140         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23141         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
23142         HelperValStmt = buildPreInits(Context, Captures);
23143       }
23144     }
23145   }
23146 
23147   return new (Context)
23148       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
23149                             Kind, ValExpr, HelperValStmt);
23150 }
23151 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)23152 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
23153     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
23154     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
23155     SourceLocation KindLoc, SourceLocation EndLoc) {
23156   if (getLangOpts().OpenMP < 50) {
23157     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23158         Kind != OMPC_DEFAULTMAP_scalar) {
23159       std::string Value;
23160       SourceLocation Loc;
23161       Value += "'";
23162       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23163         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23164                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
23165         Loc = MLoc;
23166       } else {
23167         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23168                                                OMPC_DEFAULTMAP_scalar);
23169         Loc = KindLoc;
23170       }
23171       Value += "'";
23172       Diag(Loc, diag::err_omp_unexpected_clause_value)
23173           << Value << getOpenMPClauseName(OMPC_defaultmap);
23174       return nullptr;
23175     }
23176   } else {
23177     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
23178     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
23179                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
23180     if (!isDefaultmapKind || !isDefaultmapModifier) {
23181       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
23182       if (LangOpts.OpenMP == 50) {
23183         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
23184                                   "'firstprivate', 'none', 'default'";
23185         if (!isDefaultmapKind && isDefaultmapModifier) {
23186           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23187               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23188         } else if (isDefaultmapKind && !isDefaultmapModifier) {
23189           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23190               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23191         } else {
23192           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23193               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23194           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23195               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23196         }
23197       } else {
23198         StringRef ModifierValue =
23199             "'alloc', 'from', 'to', 'tofrom', "
23200             "'firstprivate', 'none', 'default', 'present'";
23201         if (!isDefaultmapKind && isDefaultmapModifier) {
23202           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23203               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23204         } else if (isDefaultmapKind && !isDefaultmapModifier) {
23205           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23206               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23207         } else {
23208           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23209               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23210           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23211               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23212         }
23213       }
23214       return nullptr;
23215     }
23216 
23217     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
23218     //  At most one defaultmap clause for each category can appear on the
23219     //  directive.
23220     if (DSAStack->checkDefaultmapCategory(Kind)) {
23221       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23222       return nullptr;
23223     }
23224   }
23225   if (Kind == OMPC_DEFAULTMAP_unknown) {
23226     // Variable category is not specified - mark all categories.
23227     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23228     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23229     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23230   } else {
23231     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23232   }
23233 
23234   return new (Context)
23235       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
23236 }
23237 
ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)23238 bool Sema::ActOnStartOpenMPDeclareTargetContext(
23239     DeclareTargetContextInfo &DTCI) {
23240   DeclContext *CurLexicalContext = getCurLexicalContext();
23241   if (!CurLexicalContext->isFileContext() &&
23242       !CurLexicalContext->isExternCContext() &&
23243       !CurLexicalContext->isExternCXXContext() &&
23244       !isa<CXXRecordDecl>(CurLexicalContext) &&
23245       !isa<ClassTemplateDecl>(CurLexicalContext) &&
23246       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
23247       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
23248     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
23249     return false;
23250   }
23251 
23252   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23253   if (getLangOpts().HIP)
23254     Diag(DTCI.Loc, diag::warn_hip_omp_target_directives);
23255 
23256   DeclareTargetNesting.push_back(DTCI);
23257   return true;
23258 }
23259 
23260 const Sema::DeclareTargetContextInfo
ActOnOpenMPEndDeclareTargetDirective()23261 Sema::ActOnOpenMPEndDeclareTargetDirective() {
23262   assert(!DeclareTargetNesting.empty() &&
23263          "check isInOpenMPDeclareTargetContext() first!");
23264   return DeclareTargetNesting.pop_back_val();
23265 }
23266 
ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)23267 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
23268     DeclareTargetContextInfo &DTCI) {
23269   for (auto &It : DTCI.ExplicitlyMapped)
23270     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
23271 }
23272 
DiagnoseUnterminatedOpenMPDeclareTarget()23273 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
23274   if (DeclareTargetNesting.empty())
23275     return;
23276   DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23277   Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
23278       << getOpenMPDirectiveName(DTCI.Kind);
23279 }
23280 
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)23281 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
23282                                                CXXScopeSpec &ScopeSpec,
23283                                                const DeclarationNameInfo &Id) {
23284   LookupResult Lookup(*this, Id, LookupOrdinaryName);
23285   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
23286 
23287   if (Lookup.isAmbiguous())
23288     return nullptr;
23289   Lookup.suppressDiagnostics();
23290 
23291   if (!Lookup.isSingleResult()) {
23292     VarOrFuncDeclFilterCCC CCC(*this);
23293     if (TypoCorrection Corrected =
23294             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
23295                         CTK_ErrorRecovery)) {
23296       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
23297                                   << Id.getName());
23298       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
23299       return nullptr;
23300     }
23301 
23302     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
23303     return nullptr;
23304   }
23305 
23306   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
23307   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23308       !isa<FunctionTemplateDecl>(ND)) {
23309     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
23310     return nullptr;
23311   }
23312   return ND;
23313 }
23314 
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,DeclareTargetContextInfo & DTCI)23315 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
23316                                         OMPDeclareTargetDeclAttr::MapTypeTy MT,
23317                                         DeclareTargetContextInfo &DTCI) {
23318   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23319           isa<FunctionTemplateDecl>(ND)) &&
23320          "Expected variable, function or function template.");
23321 
23322   // Diagnose marking after use as it may lead to incorrect diagnosis and
23323   // codegen.
23324   if (LangOpts.OpenMP >= 50 &&
23325       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
23326     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23327 
23328   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23329   if (getLangOpts().HIP)
23330     Diag(Loc, diag::warn_hip_omp_target_directives);
23331 
23332   // Explicit declare target lists have precedence.
23333   const unsigned Level = -1;
23334 
23335   auto *VD = cast<ValueDecl>(ND);
23336   std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23337       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23338   if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
23339       (*ActiveAttr)->getLevel() == Level) {
23340     Diag(Loc, diag::err_omp_device_type_mismatch)
23341         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
23342         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23343                (*ActiveAttr)->getDevType());
23344     return;
23345   }
23346   if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23347       (*ActiveAttr)->getLevel() == Level) {
23348     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23349     return;
23350   }
23351 
23352   if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23353     return;
23354 
23355   Expr *IndirectE = nullptr;
23356   bool IsIndirect = false;
23357   if (DTCI.Indirect) {
23358     IndirectE = *DTCI.Indirect;
23359     if (!IndirectE)
23360       IsIndirect = true;
23361   }
23362   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23363       Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
23364       SourceRange(Loc, Loc));
23365   ND->addAttr(A);
23366   if (ASTMutationListener *ML = Context.getASTMutationListener())
23367     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23368   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
23369   if (auto *VD = dyn_cast<VarDecl>(ND);
23370       LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
23371       VD->hasGlobalStorage())
23372     ActOnOpenMPDeclareTargetInitializer(ND);
23373 }
23374 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)23375 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
23376                                      Sema &SemaRef, Decl *D) {
23377   if (!D || !isa<VarDecl>(D))
23378     return;
23379   auto *VD = cast<VarDecl>(D);
23380   std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
23381       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23382   if (SemaRef.LangOpts.OpenMP >= 50 &&
23383       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
23384        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
23385       VD->hasGlobalStorage()) {
23386     if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23387                    *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23388       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
23389       // If a lambda declaration and definition appears between a
23390       // declare target directive and the matching end declare target
23391       // directive, all variables that are captured by the lambda
23392       // expression must also appear in a to clause.
23393       SemaRef.Diag(VD->getLocation(),
23394                    diag::err_omp_lambda_capture_in_declare_target_not_to);
23395       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
23396           << VD << 0 << SR;
23397       return;
23398     }
23399   }
23400   if (MapTy)
23401     return;
23402   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
23403   SemaRef.Diag(SL, diag::note_used_here) << SR;
23404 }
23405 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)23406 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
23407                                    Sema &SemaRef, DSAStackTy *Stack,
23408                                    ValueDecl *VD) {
23409   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23410          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
23411                            /*FullCheck=*/false);
23412 }
23413 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)23414 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
23415                                             SourceLocation IdLoc) {
23416   if (!D || D->isInvalidDecl())
23417     return;
23418   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
23419   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
23420   if (auto *VD = dyn_cast<VarDecl>(D)) {
23421     // Only global variables can be marked as declare target.
23422     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23423         !VD->isStaticDataMember())
23424       return;
23425     // 2.10.6: threadprivate variable cannot appear in a declare target
23426     // directive.
23427     if (DSAStack->isThreadPrivate(VD)) {
23428       Diag(SL, diag::err_omp_threadprivate_in_target);
23429       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
23430       return;
23431     }
23432   }
23433   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23434     D = FTD->getTemplatedDecl();
23435   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
23436     std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23437         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23438     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23439       Diag(IdLoc, diag::err_omp_function_in_link_clause);
23440       Diag(FD->getLocation(), diag::note_defined_here) << FD;
23441       return;
23442     }
23443   }
23444   if (auto *VD = dyn_cast<ValueDecl>(D)) {
23445     // Problem if any with var declared with incomplete type will be reported
23446     // as normal, so no need to check it here.
23447     if ((E || !VD->getType()->isIncompleteType()) &&
23448         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
23449       return;
23450     if (!E && isInOpenMPDeclareTargetContext()) {
23451       // Checking declaration inside declare target region.
23452       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23453           isa<FunctionTemplateDecl>(D)) {
23454         std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23455             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23456         unsigned Level = DeclareTargetNesting.size();
23457         if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23458           return;
23459         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23460         Expr *IndirectE = nullptr;
23461         bool IsIndirect = false;
23462         if (DTCI.Indirect) {
23463           IndirectE = *DTCI.Indirect;
23464           if (!IndirectE)
23465             IsIndirect = true;
23466         }
23467         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23468             Context,
23469             getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23470                                        : OMPDeclareTargetDeclAttr::MT_To,
23471             DTCI.DT, IndirectE, IsIndirect, Level,
23472             SourceRange(DTCI.Loc, DTCI.Loc));
23473         D->addAttr(A);
23474         if (ASTMutationListener *ML = Context.getASTMutationListener())
23475           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23476       }
23477       return;
23478     }
23479   }
23480   if (!E)
23481     return;
23482   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
23483 }
23484 
23485 /// This class visits every VarDecl that the initializer references and adds
23486 /// OMPDeclareTargetDeclAttr to each of them.
23487 class GlobalDeclRefChecker final
23488     : public StmtVisitor<GlobalDeclRefChecker> {
23489   SmallVector<VarDecl *> DeclVector;
23490   Attr *A;
23491 
23492 public:
23493   /// A StmtVisitor class function that visits all DeclRefExpr and adds
23494   /// OMPDeclareTargetDeclAttr to them.
VisitDeclRefExpr(DeclRefExpr * Node)23495   void VisitDeclRefExpr(DeclRefExpr *Node) {
23496     if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) {
23497       VD->addAttr(A);
23498       DeclVector.push_back(VD);
23499     }
23500   }
23501   /// A function that iterates across each of the Expr's children.
VisitExpr(Expr * Ex)23502   void VisitExpr(Expr *Ex) {
23503     for (auto *Child : Ex->children()) {
23504       Visit(Child);
23505     }
23506   }
23507   /// A function that keeps a record of all the Decls that are variables, has
23508   /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop
23509   /// each Decl one at a time and use the inherited 'visit' functions to look
23510   /// for DeclRefExpr.
declareTargetInitializer(Decl * TD)23511   void declareTargetInitializer(Decl *TD) {
23512     A = TD->getAttr<OMPDeclareTargetDeclAttr>();
23513     DeclVector.push_back(cast<VarDecl>(TD));
23514     while (!DeclVector.empty()) {
23515       VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23516       if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
23517           TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) {
23518         if (Expr *Ex = TargetVarDecl->getInit())
23519           Visit(Ex);
23520       }
23521     }
23522   }
23523 };
23524 
23525 /// Adding OMPDeclareTargetDeclAttr to variables with static storage
23526 /// duration that are referenced in the initializer expression list of
23527 /// variables with static storage duration in declare target directive.
ActOnOpenMPDeclareTargetInitializer(Decl * TargetDecl)23528 void Sema::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) {
23529   GlobalDeclRefChecker Checker;
23530   if (isa<VarDecl>(TargetDecl))
23531     Checker.declareTargetInitializer(TargetDecl);
23532 }
23533 
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)23534 OMPClause *Sema::ActOnOpenMPToClause(
23535     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23536     ArrayRef<SourceLocation> MotionModifiersLoc,
23537     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23538     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23539     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23540   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23541                                           OMPC_MOTION_MODIFIER_unknown};
23542   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23543 
23544   // Process motion-modifiers, flag errors for duplicate modifiers.
23545   unsigned Count = 0;
23546   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23547     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23548         llvm::is_contained(Modifiers, MotionModifiers[I])) {
23549       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23550       continue;
23551     }
23552     assert(Count < NumberOfOMPMotionModifiers &&
23553            "Modifiers exceed the allowed number of motion modifiers");
23554     Modifiers[Count] = MotionModifiers[I];
23555     ModifiersLoc[Count] = MotionModifiersLoc[I];
23556     ++Count;
23557   }
23558 
23559   MappableVarListInfo MVLI(VarList);
23560   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
23561                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
23562   if (MVLI.ProcessedVarList.empty())
23563     return nullptr;
23564 
23565   return OMPToClause::Create(
23566       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23567       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23568       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23569 }
23570 
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)23571 OMPClause *Sema::ActOnOpenMPFromClause(
23572     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23573     ArrayRef<SourceLocation> MotionModifiersLoc,
23574     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23575     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23576     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23577   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23578                                           OMPC_MOTION_MODIFIER_unknown};
23579   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23580 
23581   // Process motion-modifiers, flag errors for duplicate modifiers.
23582   unsigned Count = 0;
23583   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23584     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23585         llvm::is_contained(Modifiers, MotionModifiers[I])) {
23586       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23587       continue;
23588     }
23589     assert(Count < NumberOfOMPMotionModifiers &&
23590            "Modifiers exceed the allowed number of motion modifiers");
23591     Modifiers[Count] = MotionModifiers[I];
23592     ModifiersLoc[Count] = MotionModifiersLoc[I];
23593     ++Count;
23594   }
23595 
23596   MappableVarListInfo MVLI(VarList);
23597   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
23598                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
23599   if (MVLI.ProcessedVarList.empty())
23600     return nullptr;
23601 
23602   return OMPFromClause::Create(
23603       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23604       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23605       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23606 }
23607 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)23608 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
23609                                                const OMPVarListLocTy &Locs) {
23610   MappableVarListInfo MVLI(VarList);
23611   SmallVector<Expr *, 8> PrivateCopies;
23612   SmallVector<Expr *, 8> Inits;
23613 
23614   for (Expr *RefExpr : VarList) {
23615     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
23616     SourceLocation ELoc;
23617     SourceRange ERange;
23618     Expr *SimpleRefExpr = RefExpr;
23619     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23620     if (Res.second) {
23621       // It will be analyzed later.
23622       MVLI.ProcessedVarList.push_back(RefExpr);
23623       PrivateCopies.push_back(nullptr);
23624       Inits.push_back(nullptr);
23625     }
23626     ValueDecl *D = Res.first;
23627     if (!D)
23628       continue;
23629 
23630     QualType Type = D->getType();
23631     Type = Type.getNonReferenceType().getUnqualifiedType();
23632 
23633     auto *VD = dyn_cast<VarDecl>(D);
23634 
23635     // Item should be a pointer or reference to pointer.
23636     if (!Type->isPointerType()) {
23637       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23638           << 0 << RefExpr->getSourceRange();
23639       continue;
23640     }
23641 
23642     // Build the private variable and the expression that refers to it.
23643     auto VDPrivate =
23644         buildVarDecl(*this, ELoc, Type, D->getName(),
23645                      D->hasAttrs() ? &D->getAttrs() : nullptr,
23646                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
23647     if (VDPrivate->isInvalidDecl())
23648       continue;
23649 
23650     CurContext->addDecl(VDPrivate);
23651     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23652         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23653 
23654     // Add temporary variable to initialize the private copy of the pointer.
23655     VarDecl *VDInit =
23656         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23657     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23658         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23659     AddInitializerToDecl(VDPrivate,
23660                          DefaultLvalueConversion(VDInitRefExpr).get(),
23661                          /*DirectInit=*/false);
23662 
23663     // If required, build a capture to implement the privatization initialized
23664     // with the current list item value.
23665     DeclRefExpr *Ref = nullptr;
23666     if (!VD)
23667       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23668     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23669     PrivateCopies.push_back(VDPrivateRefExpr);
23670     Inits.push_back(VDInitRefExpr);
23671 
23672     // We need to add a data sharing attribute for this variable to make sure it
23673     // is correctly captured. A variable that shows up in a use_device_ptr has
23674     // similar properties of a first private variable.
23675     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23676 
23677     // Create a mappable component for the list item. List items in this clause
23678     // only need a component.
23679     MVLI.VarBaseDeclarations.push_back(D);
23680     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23681     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23682                                            /*IsNonContiguous=*/false);
23683   }
23684 
23685   if (MVLI.ProcessedVarList.empty())
23686     return nullptr;
23687 
23688   return OMPUseDevicePtrClause::Create(
23689       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23690       MVLI.VarBaseDeclarations, MVLI.VarComponents);
23691 }
23692 
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)23693 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
23694                                                 const OMPVarListLocTy &Locs) {
23695   MappableVarListInfo MVLI(VarList);
23696 
23697   for (Expr *RefExpr : VarList) {
23698     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
23699     SourceLocation ELoc;
23700     SourceRange ERange;
23701     Expr *SimpleRefExpr = RefExpr;
23702     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23703                               /*AllowArraySection=*/true);
23704     if (Res.second) {
23705       // It will be analyzed later.
23706       MVLI.ProcessedVarList.push_back(RefExpr);
23707     }
23708     ValueDecl *D = Res.first;
23709     if (!D)
23710       continue;
23711     auto *VD = dyn_cast<VarDecl>(D);
23712 
23713     // If required, build a capture to implement the privatization initialized
23714     // with the current list item value.
23715     DeclRefExpr *Ref = nullptr;
23716     if (!VD)
23717       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23718     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23719 
23720     // We need to add a data sharing attribute for this variable to make sure it
23721     // is correctly captured. A variable that shows up in a use_device_addr has
23722     // similar properties of a first private variable.
23723     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23724 
23725     // Create a mappable component for the list item. List items in this clause
23726     // only need a component.
23727     MVLI.VarBaseDeclarations.push_back(D);
23728     MVLI.VarComponents.emplace_back();
23729     Expr *Component = SimpleRefExpr;
23730     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23731                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23732       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23733     MVLI.VarComponents.back().emplace_back(Component, D,
23734                                            /*IsNonContiguous=*/false);
23735   }
23736 
23737   if (MVLI.ProcessedVarList.empty())
23738     return nullptr;
23739 
23740   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23741                                         MVLI.VarBaseDeclarations,
23742                                         MVLI.VarComponents);
23743 }
23744 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)23745 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23746                                               const OMPVarListLocTy &Locs) {
23747   MappableVarListInfo MVLI(VarList);
23748   for (Expr *RefExpr : VarList) {
23749     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23750     SourceLocation ELoc;
23751     SourceRange ERange;
23752     Expr *SimpleRefExpr = RefExpr;
23753     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23754     if (Res.second) {
23755       // It will be analyzed later.
23756       MVLI.ProcessedVarList.push_back(RefExpr);
23757     }
23758     ValueDecl *D = Res.first;
23759     if (!D)
23760       continue;
23761 
23762     QualType Type = D->getType();
23763     // item should be a pointer or array or reference to pointer or array
23764     if (!Type.getNonReferenceType()->isPointerType() &&
23765         !Type.getNonReferenceType()->isArrayType()) {
23766       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23767           << 0 << RefExpr->getSourceRange();
23768       continue;
23769     }
23770 
23771     // Check if the declaration in the clause does not show up in any data
23772     // sharing attribute.
23773     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23774     if (isOpenMPPrivate(DVar.CKind)) {
23775       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23776           << getOpenMPClauseName(DVar.CKind)
23777           << getOpenMPClauseName(OMPC_is_device_ptr)
23778           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23779       reportOriginalDsa(*this, DSAStack, D, DVar);
23780       continue;
23781     }
23782 
23783     const Expr *ConflictExpr;
23784     if (DSAStack->checkMappableExprComponentListsForDecl(
23785             D, /*CurrentRegionOnly=*/true,
23786             [&ConflictExpr](
23787                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23788                 OpenMPClauseKind) -> bool {
23789               ConflictExpr = R.front().getAssociatedExpression();
23790               return true;
23791             })) {
23792       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23793       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23794           << ConflictExpr->getSourceRange();
23795       continue;
23796     }
23797 
23798     // Store the components in the stack so that they can be used to check
23799     // against other clauses later on.
23800     OMPClauseMappableExprCommon::MappableComponent MC(
23801         SimpleRefExpr, D, /*IsNonContiguous=*/false);
23802     DSAStack->addMappableExpressionComponents(
23803         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23804 
23805     // Record the expression we've just processed.
23806     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23807 
23808     // Create a mappable component for the list item. List items in this clause
23809     // only need a component. We use a null declaration to signal fields in
23810     // 'this'.
23811     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23812             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23813            "Unexpected device pointer expression!");
23814     MVLI.VarBaseDeclarations.push_back(
23815         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23816     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23817     MVLI.VarComponents.back().push_back(MC);
23818   }
23819 
23820   if (MVLI.ProcessedVarList.empty())
23821     return nullptr;
23822 
23823   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23824                                       MVLI.VarBaseDeclarations,
23825                                       MVLI.VarComponents);
23826 }
23827 
ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)23828 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23829                                                 const OMPVarListLocTy &Locs) {
23830   MappableVarListInfo MVLI(VarList);
23831   for (Expr *RefExpr : VarList) {
23832     assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23833     SourceLocation ELoc;
23834     SourceRange ERange;
23835     Expr *SimpleRefExpr = RefExpr;
23836     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23837                               /*AllowArraySection=*/true);
23838     if (Res.second) {
23839       // It will be analyzed later.
23840       MVLI.ProcessedVarList.push_back(RefExpr);
23841     }
23842     ValueDecl *D = Res.first;
23843     if (!D)
23844       continue;
23845 
23846     // Check if the declaration in the clause does not show up in any data
23847     // sharing attribute.
23848     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23849     if (isOpenMPPrivate(DVar.CKind)) {
23850       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23851           << getOpenMPClauseName(DVar.CKind)
23852           << getOpenMPClauseName(OMPC_has_device_addr)
23853           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23854       reportOriginalDsa(*this, DSAStack, D, DVar);
23855       continue;
23856     }
23857 
23858     const Expr *ConflictExpr;
23859     if (DSAStack->checkMappableExprComponentListsForDecl(
23860             D, /*CurrentRegionOnly=*/true,
23861             [&ConflictExpr](
23862                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23863                 OpenMPClauseKind) -> bool {
23864               ConflictExpr = R.front().getAssociatedExpression();
23865               return true;
23866             })) {
23867       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23868       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23869           << ConflictExpr->getSourceRange();
23870       continue;
23871     }
23872 
23873     // Store the components in the stack so that they can be used to check
23874     // against other clauses later on.
23875     Expr *Component = SimpleRefExpr;
23876     auto *VD = dyn_cast<VarDecl>(D);
23877     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23878                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23879       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23880     OMPClauseMappableExprCommon::MappableComponent MC(
23881         Component, D, /*IsNonContiguous=*/false);
23882     DSAStack->addMappableExpressionComponents(
23883         D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23884 
23885     // Record the expression we've just processed.
23886     if (!VD && !CurContext->isDependentContext()) {
23887       DeclRefExpr *Ref =
23888           buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23889       assert(Ref && "has_device_addr capture failed");
23890       MVLI.ProcessedVarList.push_back(Ref);
23891     } else
23892       MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23893 
23894     // Create a mappable component for the list item. List items in this clause
23895     // only need a component. We use a null declaration to signal fields in
23896     // 'this'.
23897     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23898             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23899            "Unexpected device pointer expression!");
23900     MVLI.VarBaseDeclarations.push_back(
23901         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23902     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23903     MVLI.VarComponents.back().push_back(MC);
23904   }
23905 
23906   if (MVLI.ProcessedVarList.empty())
23907     return nullptr;
23908 
23909   return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23910                                         MVLI.VarBaseDeclarations,
23911                                         MVLI.VarComponents);
23912 }
23913 
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23914 OMPClause *Sema::ActOnOpenMPAllocateClause(
23915     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23916     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23917   if (Allocator) {
23918     // OpenMP [2.11.4 allocate Clause, Description]
23919     // allocator is an expression of omp_allocator_handle_t type.
23920     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23921       return nullptr;
23922 
23923     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23924     if (AllocatorRes.isInvalid())
23925       return nullptr;
23926     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23927                                              DSAStack->getOMPAllocatorHandleT(),
23928                                              Sema::AA_Initializing,
23929                                              /*AllowExplicit=*/true);
23930     if (AllocatorRes.isInvalid())
23931       return nullptr;
23932     Allocator = AllocatorRes.get();
23933   } else {
23934     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23935     // allocate clauses that appear on a target construct or on constructs in a
23936     // target region must specify an allocator expression unless a requires
23937     // directive with the dynamic_allocators clause is present in the same
23938     // compilation unit.
23939     if (LangOpts.OpenMPIsTargetDevice &&
23940         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23941       targetDiag(StartLoc, diag::err_expected_allocator_expression);
23942   }
23943   // Analyze and build list of variables.
23944   SmallVector<Expr *, 8> Vars;
23945   for (Expr *RefExpr : VarList) {
23946     assert(RefExpr && "NULL expr in OpenMP private clause.");
23947     SourceLocation ELoc;
23948     SourceRange ERange;
23949     Expr *SimpleRefExpr = RefExpr;
23950     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23951     if (Res.second) {
23952       // It will be analyzed later.
23953       Vars.push_back(RefExpr);
23954     }
23955     ValueDecl *D = Res.first;
23956     if (!D)
23957       continue;
23958 
23959     auto *VD = dyn_cast<VarDecl>(D);
23960     DeclRefExpr *Ref = nullptr;
23961     if (!VD && !CurContext->isDependentContext())
23962       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23963     Vars.push_back((VD || CurContext->isDependentContext())
23964                        ? RefExpr->IgnoreParens()
23965                        : Ref);
23966   }
23967 
23968   if (Vars.empty())
23969     return nullptr;
23970 
23971   if (Allocator)
23972     DSAStack->addInnerAllocatorExpr(Allocator);
23973   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23974                                    ColonLoc, EndLoc, Vars);
23975 }
23976 
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)23977 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23978                                               SourceLocation StartLoc,
23979                                               SourceLocation LParenLoc,
23980                                               SourceLocation EndLoc) {
23981   SmallVector<Expr *, 8> Vars;
23982   for (Expr *RefExpr : VarList) {
23983     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23984     SourceLocation ELoc;
23985     SourceRange ERange;
23986     Expr *SimpleRefExpr = RefExpr;
23987     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23988     if (Res.second)
23989       // It will be analyzed later.
23990       Vars.push_back(RefExpr);
23991     ValueDecl *D = Res.first;
23992     if (!D)
23993       continue;
23994 
23995     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23996     // A list-item cannot appear in more than one nontemporal clause.
23997     if (const Expr *PrevRef =
23998             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23999       Diag(ELoc, diag::err_omp_used_in_clause_twice)
24000           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
24001       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
24002           << getOpenMPClauseName(OMPC_nontemporal);
24003       continue;
24004     }
24005 
24006     Vars.push_back(RefExpr);
24007   }
24008 
24009   if (Vars.empty())
24010     return nullptr;
24011 
24012   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24013                                       Vars);
24014 }
24015 
ActOnOpenMPScopeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)24016 StmtResult Sema::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
24017                                            Stmt *AStmt, SourceLocation StartLoc,
24018                                            SourceLocation EndLoc) {
24019   if (!AStmt)
24020     return StmtError();
24021 
24022   setFunctionHasBranchProtectedScope();
24023 
24024   return OMPScopeDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
24025 }
24026 
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)24027 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
24028                                             SourceLocation StartLoc,
24029                                             SourceLocation LParenLoc,
24030                                             SourceLocation EndLoc) {
24031   SmallVector<Expr *, 8> Vars;
24032   for (Expr *RefExpr : VarList) {
24033     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24034     SourceLocation ELoc;
24035     SourceRange ERange;
24036     Expr *SimpleRefExpr = RefExpr;
24037     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24038                               /*AllowArraySection=*/true);
24039     if (Res.second)
24040       // It will be analyzed later.
24041       Vars.push_back(RefExpr);
24042     ValueDecl *D = Res.first;
24043     if (!D)
24044       continue;
24045 
24046     const DSAStackTy::DSAVarData DVar =
24047         DSAStack->getTopDSA(D, /*FromParent=*/true);
24048     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24049     // A list item that appears in the inclusive or exclusive clause must appear
24050     // in a reduction clause with the inscan modifier on the enclosing
24051     // worksharing-loop, worksharing-loop SIMD, or simd construct.
24052     if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
24053       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24054           << RefExpr->getSourceRange();
24055 
24056     if (DSAStack->getParentDirective() != OMPD_unknown)
24057       DSAStack->markDeclAsUsedInScanDirective(D);
24058     Vars.push_back(RefExpr);
24059   }
24060 
24061   if (Vars.empty())
24062     return nullptr;
24063 
24064   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24065 }
24066 
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)24067 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
24068                                             SourceLocation StartLoc,
24069                                             SourceLocation LParenLoc,
24070                                             SourceLocation EndLoc) {
24071   SmallVector<Expr *, 8> Vars;
24072   for (Expr *RefExpr : VarList) {
24073     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24074     SourceLocation ELoc;
24075     SourceRange ERange;
24076     Expr *SimpleRefExpr = RefExpr;
24077     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24078                               /*AllowArraySection=*/true);
24079     if (Res.second)
24080       // It will be analyzed later.
24081       Vars.push_back(RefExpr);
24082     ValueDecl *D = Res.first;
24083     if (!D)
24084       continue;
24085 
24086     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
24087     DSAStackTy::DSAVarData DVar;
24088     if (ParentDirective != OMPD_unknown)
24089       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
24090     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24091     // A list item that appears in the inclusive or exclusive clause must appear
24092     // in a reduction clause with the inscan modifier on the enclosing
24093     // worksharing-loop, worksharing-loop SIMD, or simd construct.
24094     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
24095         DVar.Modifier != OMPC_REDUCTION_inscan) {
24096       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24097           << RefExpr->getSourceRange();
24098     } else {
24099       DSAStack->markDeclAsUsedInScanDirective(D);
24100     }
24101     Vars.push_back(RefExpr);
24102   }
24103 
24104   if (Vars.empty())
24105     return nullptr;
24106 
24107   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24108 }
24109 
24110 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)24111 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
24112   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24113   if (!OMPAlloctraitT.isNull())
24114     return true;
24115   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
24116   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
24117   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
24118     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
24119     return false;
24120   }
24121   Stack->setOMPAlloctraitT(PT.get());
24122   return true;
24123 }
24124 
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)24125 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
24126     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
24127     ArrayRef<UsesAllocatorsData> Data) {
24128   // OpenMP [2.12.5, target Construct]
24129   // allocator is an identifier of omp_allocator_handle_t type.
24130   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
24131     return nullptr;
24132   // OpenMP [2.12.5, target Construct]
24133   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
24134   if (llvm::any_of(
24135           Data,
24136           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
24137       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
24138     return nullptr;
24139   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
24140   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
24141     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
24142     StringRef Allocator =
24143         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24144     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
24145     PredefinedAllocators.insert(LookupSingleName(
24146         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
24147   }
24148 
24149   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
24150   for (const UsesAllocatorsData &D : Data) {
24151     Expr *AllocatorExpr = nullptr;
24152     // Check allocator expression.
24153     if (D.Allocator->isTypeDependent()) {
24154       AllocatorExpr = D.Allocator;
24155     } else {
24156       // Traits were specified - need to assign new allocator to the specified
24157       // allocator, so it must be an lvalue.
24158       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
24159       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24160       bool IsPredefinedAllocator = false;
24161       if (DRE) {
24162         OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24163             getAllocatorKind(*this, DSAStack, AllocatorExpr);
24164         IsPredefinedAllocator =
24165             AllocatorTy !=
24166             OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24167       }
24168       QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
24169       QualType AllocatorExprType = AllocatorExpr->getType();
24170       bool IsTypeCompatible = IsPredefinedAllocator;
24171       IsTypeCompatible = IsTypeCompatible ||
24172                          Context.hasSameUnqualifiedType(AllocatorExprType,
24173                                                         OMPAllocatorHandleT);
24174       IsTypeCompatible =
24175           IsTypeCompatible ||
24176           Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
24177       bool IsNonConstantLValue =
24178           !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
24179       if (!DRE || !IsTypeCompatible ||
24180           (!IsPredefinedAllocator && !IsNonConstantLValue)) {
24181         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
24182             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
24183             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
24184         continue;
24185       }
24186       // OpenMP [2.12.5, target Construct]
24187       // Predefined allocators appearing in a uses_allocators clause cannot have
24188       // traits specified.
24189       if (IsPredefinedAllocator && D.AllocatorTraits) {
24190         Diag(D.AllocatorTraits->getExprLoc(),
24191              diag::err_omp_predefined_allocator_with_traits)
24192             << D.AllocatorTraits->getSourceRange();
24193         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
24194             << cast<NamedDecl>(DRE->getDecl())->getName()
24195             << D.Allocator->getSourceRange();
24196         continue;
24197       }
24198       // OpenMP [2.12.5, target Construct]
24199       // Non-predefined allocators appearing in a uses_allocators clause must
24200       // have traits specified.
24201       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
24202         Diag(D.Allocator->getExprLoc(),
24203              diag::err_omp_nonpredefined_allocator_without_traits);
24204         continue;
24205       }
24206       // No allocator traits - just convert it to rvalue.
24207       if (!D.AllocatorTraits)
24208         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
24209       DSAStack->addUsesAllocatorsDecl(
24210           DRE->getDecl(),
24211           IsPredefinedAllocator
24212               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
24213               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
24214     }
24215     Expr *AllocatorTraitsExpr = nullptr;
24216     if (D.AllocatorTraits) {
24217       if (D.AllocatorTraits->isTypeDependent()) {
24218         AllocatorTraitsExpr = D.AllocatorTraits;
24219       } else {
24220         // OpenMP [2.12.5, target Construct]
24221         // Arrays that contain allocator traits that appear in a uses_allocators
24222         // clause must be constant arrays, have constant values and be defined
24223         // in the same scope as the construct in which the clause appears.
24224         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
24225         // Check that traits expr is a constant array.
24226         QualType TraitTy;
24227         if (const ArrayType *Ty =
24228                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
24229           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24230             TraitTy = ConstArrayTy->getElementType();
24231         if (TraitTy.isNull() ||
24232             !(Context.hasSameUnqualifiedType(TraitTy,
24233                                              DSAStack->getOMPAlloctraitT()) ||
24234               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
24235                                          /*CompareUnqualified=*/true))) {
24236           Diag(D.AllocatorTraits->getExprLoc(),
24237                diag::err_omp_expected_array_alloctraits)
24238               << AllocatorTraitsExpr->getType();
24239           continue;
24240         }
24241         // Do not map by default allocator traits if it is a standalone
24242         // variable.
24243         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24244           DSAStack->addUsesAllocatorsDecl(
24245               DRE->getDecl(),
24246               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24247       }
24248     }
24249     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
24250     NewD.Allocator = AllocatorExpr;
24251     NewD.AllocatorTraits = AllocatorTraitsExpr;
24252     NewD.LParenLoc = D.LParenLoc;
24253     NewD.RParenLoc = D.RParenLoc;
24254   }
24255   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24256                                          NewData);
24257 }
24258 
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)24259 OMPClause *Sema::ActOnOpenMPAffinityClause(
24260     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
24261     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
24262   SmallVector<Expr *, 8> Vars;
24263   for (Expr *RefExpr : Locators) {
24264     assert(RefExpr && "NULL expr in OpenMP shared clause.");
24265     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24266       // It will be analyzed later.
24267       Vars.push_back(RefExpr);
24268       continue;
24269     }
24270 
24271     SourceLocation ELoc = RefExpr->getExprLoc();
24272     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
24273 
24274     if (!SimpleExpr->isLValue()) {
24275       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24276           << 1 << 0 << RefExpr->getSourceRange();
24277       continue;
24278     }
24279 
24280     ExprResult Res;
24281     {
24282       Sema::TentativeAnalysisScope Trap(*this);
24283       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
24284     }
24285     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
24286         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24287       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24288           << 1 << 0 << RefExpr->getSourceRange();
24289       continue;
24290     }
24291     Vars.push_back(SimpleExpr);
24292   }
24293 
24294   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
24295                                    EndLoc, Modifier, Vars);
24296 }
24297 
ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,SourceLocation KindLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)24298 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
24299                                        SourceLocation KindLoc,
24300                                        SourceLocation StartLoc,
24301                                        SourceLocation LParenLoc,
24302                                        SourceLocation EndLoc) {
24303   if (Kind == OMPC_BIND_unknown) {
24304     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24305         << getListOfPossibleValues(OMPC_bind, /*First=*/0,
24306                                    /*Last=*/unsigned(OMPC_BIND_unknown))
24307         << getOpenMPClauseName(OMPC_bind);
24308     return nullptr;
24309   }
24310 
24311   return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
24312                                EndLoc);
24313 }
24314 
ActOnOpenMPXDynCGroupMemClause(Expr * Size,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)24315 OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
24316                                                 SourceLocation StartLoc,
24317                                                 SourceLocation LParenLoc,
24318                                                 SourceLocation EndLoc) {
24319   Expr *ValExpr = Size;
24320   Stmt *HelperValStmt = nullptr;
24321 
24322   // OpenMP [2.5, Restrictions]
24323   //  The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
24324   //  value.
24325   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
24326                                  /*StrictlyPositive=*/false))
24327     return nullptr;
24328 
24329   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
24330   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
24331       DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
24332   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
24333     ValExpr = MakeFullExpr(ValExpr).get();
24334     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24335     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
24336     HelperValStmt = buildPreInits(Context, Captures);
24337   }
24338 
24339   return new (Context) OMPXDynCGroupMemClause(
24340       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24341 }
24342 
ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)24343 OMPClause *Sema::ActOnOpenMPDoacrossClause(
24344     OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc,
24345     SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
24346     SourceLocation LParenLoc, SourceLocation EndLoc) {
24347 
24348   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
24349       DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24350       DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24351       DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24352       DepType != OMPC_DOACROSS_source) {
24353     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24354         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24355     return nullptr;
24356   }
24357 
24358   SmallVector<Expr *, 8> Vars;
24359   DSAStackTy::OperatorOffsetTy OpsOffs;
24360   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
24361   DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
24362       *this,
24363       DepType == OMPC_DOACROSS_source ||
24364           DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24365           DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24366       VarList, DSAStack, EndLoc);
24367   Vars = VarOffset.Vars;
24368   OpsOffs = VarOffset.OpsOffs;
24369   TotalDepCount = VarOffset.TotalDepCount;
24370   auto *C = OMPDoacrossClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24371                                       DepType, DepLoc, ColonLoc, Vars,
24372                                       TotalDepCount.getZExtValue());
24373   if (DSAStack->isParentOrderedRegion())
24374     DSAStack->addDoacrossDependClause(C, OpsOffs);
24375   return C;
24376 }
24377 
ActOnOpenMPXAttributeClause(ArrayRef<const Attr * > Attrs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)24378 OMPClause *Sema::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
24379                                              SourceLocation StartLoc,
24380                                              SourceLocation LParenLoc,
24381                                              SourceLocation EndLoc) {
24382   return new (Context) OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc);
24383 }
24384 
ActOnOpenMPXBareClause(SourceLocation StartLoc,SourceLocation EndLoc)24385 OMPClause *Sema::ActOnOpenMPXBareClause(SourceLocation StartLoc,
24386                                         SourceLocation EndLoc) {
24387   return new (Context) OMPXBareClause(StartLoc, EndLoc);
24388 }
24389