• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/Initialization.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
34 #include "clang/Sema/SemaInternal.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/Frontend/OpenMP/OMPConstants.h"
39 #include <set>
40 
41 using namespace clang;
42 using namespace llvm::omp;
43 
44 //===----------------------------------------------------------------------===//
45 // Stack of data-sharing attributes for variables
46 //===----------------------------------------------------------------------===//
47 
48 static const Expr *checkMapClauseExpressionBase(
49     Sema &SemaRef, Expr *E,
50     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
52 
53 namespace {
54 /// Default data sharing attributes, which can be applied to directive.
55 enum DefaultDataSharingAttributes {
56   DSA_unspecified = 0,       /// Data sharing attribute not specified.
57   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
58   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
59   DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
60 };
61 
62 /// Stack for tracking declarations used in OpenMP directives and
63 /// clauses and their data-sharing attributes.
64 class DSAStackTy {
65 public:
66   struct DSAVarData {
67     OpenMPDirectiveKind DKind = OMPD_unknown;
68     OpenMPClauseKind CKind = OMPC_unknown;
69     unsigned Modifier = 0;
70     const Expr *RefExpr = nullptr;
71     DeclRefExpr *PrivateCopy = nullptr;
72     SourceLocation ImplicitDSALoc;
73     bool AppliedToPointee = false;
74     DSAVarData() = default;
DSAVarData__anon0bb9e2bb0111::DSAStackTy::DSAVarData75     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
76                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
77                SourceLocation ImplicitDSALoc, unsigned Modifier,
78                bool AppliedToPointee)
79         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
80           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
81           AppliedToPointee(AppliedToPointee) {}
82   };
83   using OperatorOffsetTy =
84       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
85   using DoacrossDependMapTy =
86       llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
87   /// Kind of the declaration used in the uses_allocators clauses.
88   enum class UsesAllocatorsDeclKind {
89     /// Predefined allocator
90     PredefinedAllocator,
91     /// User-defined allocator
92     UserDefinedAllocator,
93     /// The declaration that represent allocator trait
94     AllocatorTrait,
95   };
96 
97 private:
98   struct DSAInfo {
99     OpenMPClauseKind Attributes = OMPC_unknown;
100     unsigned Modifier = 0;
101     /// Pointer to a reference expression and a flag which shows that the
102     /// variable is marked as lastprivate(true) or not (false).
103     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
104     DeclRefExpr *PrivateCopy = nullptr;
105     /// true if the attribute is applied to the pointee, not the variable
106     /// itself.
107     bool AppliedToPointee = false;
108   };
109   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
110   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
111   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
112   using LoopControlVariablesMapTy =
113       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
114   /// Struct that associates a component with the clause kind where they are
115   /// found.
116   struct MappedExprComponentTy {
117     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
118     OpenMPClauseKind Kind = OMPC_unknown;
119   };
120   using MappedExprComponentsTy =
121       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
122   using CriticalsWithHintsTy =
123       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
124   struct ReductionData {
125     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
126     SourceRange ReductionRange;
127     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
128     ReductionData() = default;
set__anon0bb9e2bb0111::DSAStackTy::ReductionData129     void set(BinaryOperatorKind BO, SourceRange RR) {
130       ReductionRange = RR;
131       ReductionOp = BO;
132     }
set__anon0bb9e2bb0111::DSAStackTy::ReductionData133     void set(const Expr *RefExpr, SourceRange RR) {
134       ReductionRange = RR;
135       ReductionOp = RefExpr;
136     }
137   };
138   using DeclReductionMapTy =
139       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
140   struct DefaultmapInfo {
141     OpenMPDefaultmapClauseModifier ImplicitBehavior =
142         OMPC_DEFAULTMAP_MODIFIER_unknown;
143     SourceLocation SLoc;
144     DefaultmapInfo() = default;
DefaultmapInfo__anon0bb9e2bb0111::DSAStackTy::DefaultmapInfo145     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
146         : ImplicitBehavior(M), SLoc(Loc) {}
147   };
148 
149   struct SharingMapTy {
150     DeclSAMapTy SharingMap;
151     DeclReductionMapTy ReductionMap;
152     UsedRefMapTy AlignedMap;
153     UsedRefMapTy NontemporalMap;
154     MappedExprComponentsTy MappedExprComponents;
155     LoopControlVariablesMapTy LCVMap;
156     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
157     SourceLocation DefaultAttrLoc;
158     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
159     OpenMPDirectiveKind Directive = OMPD_unknown;
160     DeclarationNameInfo DirectiveName;
161     Scope *CurScope = nullptr;
162     DeclContext *Context = nullptr;
163     SourceLocation ConstructLoc;
164     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
165     /// get the data (loop counters etc.) about enclosing loop-based construct.
166     /// This data is required during codegen.
167     DoacrossDependMapTy DoacrossDepends;
168     /// First argument (Expr *) contains optional argument of the
169     /// 'ordered' clause, the second one is true if the regions has 'ordered'
170     /// clause, false otherwise.
171     llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
172     unsigned AssociatedLoops = 1;
173     bool HasMutipleLoops = false;
174     const Decl *PossiblyLoopCounter = nullptr;
175     bool NowaitRegion = false;
176     bool CancelRegion = false;
177     bool LoopStart = false;
178     bool BodyComplete = false;
179     SourceLocation PrevScanLocation;
180     SourceLocation PrevOrderedLocation;
181     SourceLocation InnerTeamsRegionLoc;
182     /// Reference to the taskgroup task_reduction reference expression.
183     Expr *TaskgroupReductionRef = nullptr;
184     llvm::DenseSet<QualType> MappedClassesQualTypes;
185     SmallVector<Expr *, 4> InnerUsedAllocators;
186     llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
187     /// List of globals marked as declare target link in this target region
188     /// (isOpenMPTargetExecutionDirective(Directive) == true).
189     llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
190     /// List of decls used in inclusive/exclusive clauses of the scan directive.
191     llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
192     llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
193         UsesAllocatorsDecls;
194     Expr *DeclareMapperVar = nullptr;
SharingMapTy__anon0bb9e2bb0111::DSAStackTy::SharingMapTy195     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
196                  Scope *CurScope, SourceLocation Loc)
197         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
198           ConstructLoc(Loc) {}
199     SharingMapTy() = default;
200   };
201 
202   using StackTy = SmallVector<SharingMapTy, 4>;
203 
204   /// Stack of used declaration and their data-sharing attributes.
205   DeclSAMapTy Threadprivates;
206   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
207   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
208   /// true, if check for DSA must be from parent directive, false, if
209   /// from current directive.
210   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
211   Sema &SemaRef;
212   bool ForceCapturing = false;
213   /// true if all the variables in the target executable directives must be
214   /// captured by reference.
215   bool ForceCaptureByReferenceInTargetExecutable = false;
216   CriticalsWithHintsTy Criticals;
217   unsigned IgnoredStackElements = 0;
218 
219   /// Iterators over the stack iterate in order from innermost to outermost
220   /// directive.
221   using const_iterator = StackTy::const_reverse_iterator;
begin() const222   const_iterator begin() const {
223     return Stack.empty() ? const_iterator()
224                          : Stack.back().first.rbegin() + IgnoredStackElements;
225   }
end() const226   const_iterator end() const {
227     return Stack.empty() ? const_iterator() : Stack.back().first.rend();
228   }
229   using iterator = StackTy::reverse_iterator;
begin()230   iterator begin() {
231     return Stack.empty() ? iterator()
232                          : Stack.back().first.rbegin() + IgnoredStackElements;
233   }
end()234   iterator end() {
235     return Stack.empty() ? iterator() : Stack.back().first.rend();
236   }
237 
238   // Convenience operations to get at the elements of the stack.
239 
isStackEmpty() const240   bool isStackEmpty() const {
241     return Stack.empty() ||
242            Stack.back().second != CurrentNonCapturingFunctionScope ||
243            Stack.back().first.size() <= IgnoredStackElements;
244   }
getStackSize() const245   size_t getStackSize() const {
246     return isStackEmpty() ? 0
247                           : Stack.back().first.size() - IgnoredStackElements;
248   }
249 
getTopOfStackOrNull()250   SharingMapTy *getTopOfStackOrNull() {
251     size_t Size = getStackSize();
252     if (Size == 0)
253       return nullptr;
254     return &Stack.back().first[Size - 1];
255   }
getTopOfStackOrNull() const256   const SharingMapTy *getTopOfStackOrNull() const {
257     return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
258   }
getTopOfStack()259   SharingMapTy &getTopOfStack() {
260     assert(!isStackEmpty() && "no current directive");
261     return *getTopOfStackOrNull();
262   }
getTopOfStack() const263   const SharingMapTy &getTopOfStack() const {
264     return const_cast<DSAStackTy&>(*this).getTopOfStack();
265   }
266 
getSecondOnStackOrNull()267   SharingMapTy *getSecondOnStackOrNull() {
268     size_t Size = getStackSize();
269     if (Size <= 1)
270       return nullptr;
271     return &Stack.back().first[Size - 2];
272   }
getSecondOnStackOrNull() const273   const SharingMapTy *getSecondOnStackOrNull() const {
274     return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
275   }
276 
277   /// Get the stack element at a certain level (previously returned by
278   /// \c getNestingLevel).
279   ///
280   /// Note that nesting levels count from outermost to innermost, and this is
281   /// the reverse of our iteration order where new inner levels are pushed at
282   /// the front of the stack.
getStackElemAtLevel(unsigned Level)283   SharingMapTy &getStackElemAtLevel(unsigned Level) {
284     assert(Level < getStackSize() && "no such stack element");
285     return Stack.back().first[Level];
286   }
getStackElemAtLevel(unsigned Level) const287   const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
288     return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
289   }
290 
291   DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
292 
293   /// Checks if the variable is a local for OpenMP region.
294   bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
295 
296   /// Vector of previously declared requires directives
297   SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
298   /// omp_allocator_handle_t type.
299   QualType OMPAllocatorHandleT;
300   /// omp_depend_t type.
301   QualType OMPDependT;
302   /// omp_event_handle_t type.
303   QualType OMPEventHandleT;
304   /// omp_alloctrait_t type.
305   QualType OMPAlloctraitT;
306   /// Expression for the predefined allocators.
307   Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
308       nullptr};
309   /// Vector of previously encountered target directives
310   SmallVector<SourceLocation, 2> TargetLocations;
311   SourceLocation AtomicLocation;
312 
313 public:
DSAStackTy(Sema & S)314   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
315 
316   /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)317   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
318   /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const319   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
320   /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)321   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
322   /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const323   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
324   /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)325   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
326                     Expr *Allocator) {
327     OMPPredefinedAllocators[AllocatorKind] = Allocator;
328   }
329   /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const330   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
331     return OMPPredefinedAllocators[AllocatorKind];
332   }
333   /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)334   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
335   /// Gets omp_depend_t type.
getOMPDependT() const336   QualType getOMPDependT() const { return OMPDependT; }
337 
338   /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)339   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
340   /// Gets omp_event_handle_t type.
getOMPEventHandleT() const341   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
342 
isClauseParsingMode() const343   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const344   OpenMPClauseKind getClauseParsingMode() const {
345     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
346     return ClauseKindMode;
347   }
setClauseParsingMode(OpenMPClauseKind K)348   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
349 
isBodyComplete() const350   bool isBodyComplete() const {
351     const SharingMapTy *Top = getTopOfStackOrNull();
352     return Top && Top->BodyComplete;
353   }
setBodyComplete()354   void setBodyComplete() {
355     getTopOfStack().BodyComplete = true;
356   }
357 
isForceVarCapturing() const358   bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)359   void setForceVarCapturing(bool V) { ForceCapturing = V; }
360 
setForceCaptureByReferenceInTargetExecutable(bool V)361   void setForceCaptureByReferenceInTargetExecutable(bool V) {
362     ForceCaptureByReferenceInTargetExecutable = V;
363   }
isForceCaptureByReferenceInTargetExecutable() const364   bool isForceCaptureByReferenceInTargetExecutable() const {
365     return ForceCaptureByReferenceInTargetExecutable;
366   }
367 
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)368   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
369             Scope *CurScope, SourceLocation Loc) {
370     assert(!IgnoredStackElements &&
371            "cannot change stack while ignoring elements");
372     if (Stack.empty() ||
373         Stack.back().second != CurrentNonCapturingFunctionScope)
374       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
375     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
376     Stack.back().first.back().DefaultAttrLoc = Loc;
377   }
378 
pop()379   void pop() {
380     assert(!IgnoredStackElements &&
381            "cannot change stack while ignoring elements");
382     assert(!Stack.back().first.empty() &&
383            "Data-sharing attributes stack is empty!");
384     Stack.back().first.pop_back();
385   }
386 
387   /// RAII object to temporarily leave the scope of a directive when we want to
388   /// logically operate in its parent.
389   class ParentDirectiveScope {
390     DSAStackTy &Self;
391     bool Active;
392   public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)393     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
394         : Self(Self), Active(false) {
395       if (Activate)
396         enable();
397     }
~ParentDirectiveScope()398     ~ParentDirectiveScope() { disable(); }
disable()399     void disable() {
400       if (Active) {
401         --Self.IgnoredStackElements;
402         Active = false;
403       }
404     }
enable()405     void enable() {
406       if (!Active) {
407         ++Self.IgnoredStackElements;
408         Active = true;
409       }
410     }
411   };
412 
413   /// Marks that we're started loop parsing.
loopInit()414   void loopInit() {
415     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
416            "Expected loop-based directive.");
417     getTopOfStack().LoopStart = true;
418   }
419   /// Start capturing of the variables in the loop context.
loopStart()420   void loopStart() {
421     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
422            "Expected loop-based directive.");
423     getTopOfStack().LoopStart = false;
424   }
425   /// true, if variables are captured, false otherwise.
isLoopStarted() const426   bool isLoopStarted() const {
427     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
428            "Expected loop-based directive.");
429     return !getTopOfStack().LoopStart;
430   }
431   /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)432   void resetPossibleLoopCounter(const Decl *D = nullptr) {
433     getTopOfStack().PossiblyLoopCounter =
434         D ? D->getCanonicalDecl() : D;
435   }
436   /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const437   const Decl *getPossiblyLoopCunter() const {
438     return getTopOfStack().PossiblyLoopCounter;
439   }
440   /// Start new OpenMP region stack in new non-capturing function.
pushFunction()441   void pushFunction() {
442     assert(!IgnoredStackElements &&
443            "cannot change stack while ignoring elements");
444     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
445     assert(!isa<CapturingScopeInfo>(CurFnScope));
446     CurrentNonCapturingFunctionScope = CurFnScope;
447   }
448   /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)449   void popFunction(const FunctionScopeInfo *OldFSI) {
450     assert(!IgnoredStackElements &&
451            "cannot change stack while ignoring elements");
452     if (!Stack.empty() && Stack.back().second == OldFSI) {
453       assert(Stack.back().first.empty());
454       Stack.pop_back();
455     }
456     CurrentNonCapturingFunctionScope = nullptr;
457     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
458       if (!isa<CapturingScopeInfo>(FSI)) {
459         CurrentNonCapturingFunctionScope = FSI;
460         break;
461       }
462     }
463   }
464 
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)465   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
466     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
467   }
468   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const469   getCriticalWithHint(const DeclarationNameInfo &Name) const {
470     auto I = Criticals.find(Name.getAsString());
471     if (I != Criticals.end())
472       return I->second;
473     return std::make_pair(nullptr, llvm::APSInt());
474   }
475   /// If 'aligned' declaration for given variable \a D was not seen yet,
476   /// add it and return NULL; otherwise return previous occurrence's expression
477   /// for diagnostics.
478   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
479   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
480   /// add it and return NULL; otherwise return previous occurrence's expression
481   /// for diagnostics.
482   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
483 
484   /// Register specified variable as loop control variable.
485   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
486   /// Check if the specified variable is a loop control variable for
487   /// current region.
488   /// \return The index of the loop control variable in the list of associated
489   /// for-loops (from outer to inner).
490   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
491   /// Check if the specified variable is a loop control variable for
492   /// parent region.
493   /// \return The index of the loop control variable in the list of associated
494   /// for-loops (from outer to inner).
495   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
496   /// Check if the specified variable is a loop control variable for
497   /// current region.
498   /// \return The index of the loop control variable in the list of associated
499   /// for-loops (from outer to inner).
500   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
501                                          unsigned Level) const;
502   /// Get the loop control variable for the I-th loop (or nullptr) in
503   /// parent directive.
504   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
505 
506   /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)507   void markDeclAsUsedInScanDirective(ValueDecl *D) {
508     if (SharingMapTy *Stack = getSecondOnStackOrNull())
509       Stack->UsedInScanDirective.insert(D);
510   }
511 
512   /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const513   bool isUsedInScanDirective(ValueDecl *D) const {
514     if (const SharingMapTy *Stack = getTopOfStackOrNull())
515       return Stack->UsedInScanDirective.count(D) > 0;
516     return false;
517   }
518 
519   /// Adds explicit data sharing attribute to the specified declaration.
520   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
521               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
522               bool AppliedToPointee = false);
523 
524   /// Adds additional information for the reduction items with the reduction id
525   /// represented as an operator.
526   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
527                                  BinaryOperatorKind BOK);
528   /// Adds additional information for the reduction items with the reduction id
529   /// represented as reduction identifier.
530   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
531                                  const Expr *ReductionRef);
532   /// Returns the location and reduction operation from the innermost parent
533   /// region for the given \p D.
534   const DSAVarData
535   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
536                                    BinaryOperatorKind &BOK,
537                                    Expr *&TaskgroupDescriptor) const;
538   /// Returns the location and reduction operation from the innermost parent
539   /// region for the given \p D.
540   const DSAVarData
541   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
542                                    const Expr *&ReductionRef,
543                                    Expr *&TaskgroupDescriptor) const;
544   /// Return reduction reference expression for the current taskgroup or
545   /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const546   Expr *getTaskgroupReductionRef() const {
547     assert((getTopOfStack().Directive == OMPD_taskgroup ||
548             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
549               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
550              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
551            "taskgroup reference expression requested for non taskgroup or "
552            "parallel/worksharing directive.");
553     return getTopOfStack().TaskgroupReductionRef;
554   }
555   /// Checks if the given \p VD declaration is actually a taskgroup reduction
556   /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const557   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
558     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
559            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
560                    ->getDecl() == VD;
561   }
562 
563   /// Returns data sharing attributes from top of the stack for the
564   /// specified declaration.
565   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
566   /// Returns data-sharing attributes for the specified declaration.
567   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
568   /// Returns data-sharing attributes for the specified declaration.
569   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
570   /// Checks if the specified variables has data-sharing attributes which
571   /// match specified \a CPred predicate in any directive which matches \a DPred
572   /// predicate.
573   const DSAVarData
574   hasDSA(ValueDecl *D,
575          const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
576          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
577          bool FromParent) const;
578   /// Checks if the specified variables has data-sharing attributes which
579   /// match specified \a CPred predicate in any innermost directive which
580   /// matches \a DPred predicate.
581   const DSAVarData
582   hasInnermostDSA(ValueDecl *D,
583                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
584                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
585                   bool FromParent) const;
586   /// Checks if the specified variables has explicit data-sharing
587   /// attributes which match specified \a CPred predicate at the specified
588   /// OpenMP region.
589   bool
590   hasExplicitDSA(const ValueDecl *D,
591                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
592                  unsigned Level, bool NotLastprivate = false) const;
593 
594   /// Returns true if the directive at level \Level matches in the
595   /// specified \a DPred predicate.
596   bool hasExplicitDirective(
597       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
598       unsigned Level) const;
599 
600   /// Finds a directive which matches specified \a DPred predicate.
601   bool hasDirective(
602       const llvm::function_ref<bool(
603           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
604           DPred,
605       bool FromParent) const;
606 
607   /// Returns currently analyzed directive.
getCurrentDirective() const608   OpenMPDirectiveKind getCurrentDirective() const {
609     const SharingMapTy *Top = getTopOfStackOrNull();
610     return Top ? Top->Directive : OMPD_unknown;
611   }
612   /// Returns directive kind at specified level.
getDirective(unsigned Level) const613   OpenMPDirectiveKind getDirective(unsigned Level) const {
614     assert(!isStackEmpty() && "No directive at specified level.");
615     return getStackElemAtLevel(Level).Directive;
616   }
617   /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const618   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
619                                        unsigned OpenMPCaptureLevel) const {
620     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
621     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
622     return CaptureRegions[OpenMPCaptureLevel];
623   }
624   /// Returns parent directive.
getParentDirective() const625   OpenMPDirectiveKind getParentDirective() const {
626     const SharingMapTy *Parent = getSecondOnStackOrNull();
627     return Parent ? Parent->Directive : OMPD_unknown;
628   }
629 
630   /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)631   void addRequiresDecl(OMPRequiresDecl *RD) {
632     RequiresDecls.push_back(RD);
633   }
634 
635   /// Checks if the defined 'requires' directive has specified type of clause.
636   template <typename ClauseType>
hasRequiresDeclWithClause() const637   bool hasRequiresDeclWithClause() const {
638     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
639       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
640         return isa<ClauseType>(C);
641       });
642     });
643   }
644 
645   /// Checks for a duplicate clause amongst previously declared requires
646   /// directives
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const647   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
648     bool IsDuplicate = false;
649     for (OMPClause *CNew : ClauseList) {
650       for (const OMPRequiresDecl *D : RequiresDecls) {
651         for (const OMPClause *CPrev : D->clauselists()) {
652           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
653             SemaRef.Diag(CNew->getBeginLoc(),
654                          diag::err_omp_requires_clause_redeclaration)
655                 << getOpenMPClauseName(CNew->getClauseKind());
656             SemaRef.Diag(CPrev->getBeginLoc(),
657                          diag::note_omp_requires_previous_clause)
658                 << getOpenMPClauseName(CPrev->getClauseKind());
659             IsDuplicate = true;
660           }
661         }
662       }
663     }
664     return IsDuplicate;
665   }
666 
667   /// Add location of previously encountered target to internal vector
addTargetDirLocation(SourceLocation LocStart)668   void addTargetDirLocation(SourceLocation LocStart) {
669     TargetLocations.push_back(LocStart);
670   }
671 
672   /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)673   void addAtomicDirectiveLoc(SourceLocation Loc) {
674     if (AtomicLocation.isInvalid())
675       AtomicLocation = Loc;
676   }
677 
678   /// Returns the location of the first encountered atomic directive in the
679   /// module.
getAtomicDirectiveLoc() const680   SourceLocation getAtomicDirectiveLoc() const {
681     return AtomicLocation;
682   }
683 
684   // Return previously encountered target region locations.
getEncounteredTargetLocs() const685   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
686     return TargetLocations;
687   }
688 
689   /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)690   void setDefaultDSANone(SourceLocation Loc) {
691     getTopOfStack().DefaultAttr = DSA_none;
692     getTopOfStack().DefaultAttrLoc = Loc;
693   }
694   /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)695   void setDefaultDSAShared(SourceLocation Loc) {
696     getTopOfStack().DefaultAttr = DSA_shared;
697     getTopOfStack().DefaultAttrLoc = Loc;
698   }
699   /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)700   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
701     getTopOfStack().DefaultAttr = DSA_firstprivate;
702     getTopOfStack().DefaultAttrLoc = Loc;
703   }
704   /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)705   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
706                          OpenMPDefaultmapClauseKind Kind,
707                          SourceLocation Loc) {
708     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
709     DMI.ImplicitBehavior = M;
710     DMI.SLoc = Loc;
711   }
712   /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)713   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
714     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
715       return getTopOfStack()
716                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
717                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
718              getTopOfStack()
719                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
720                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
721              getTopOfStack()
722                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
723                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
724     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
725            OMPC_DEFAULTMAP_MODIFIER_unknown;
726   }
727 
getDefaultDSA(unsigned Level) const728   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
729     return getStackSize() <= Level ? DSA_unspecified
730                                    : getStackElemAtLevel(Level).DefaultAttr;
731   }
getDefaultDSA() const732   DefaultDataSharingAttributes getDefaultDSA() const {
733     return isStackEmpty() ? DSA_unspecified
734                           : getTopOfStack().DefaultAttr;
735   }
getDefaultDSALocation() const736   SourceLocation getDefaultDSALocation() const {
737     return isStackEmpty() ? SourceLocation()
738                           : getTopOfStack().DefaultAttrLoc;
739   }
740   OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const741   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
742     return isStackEmpty()
743                ? OMPC_DEFAULTMAP_MODIFIER_unknown
744                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
745   }
746   OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const747   getDefaultmapModifierAtLevel(unsigned Level,
748                                OpenMPDefaultmapClauseKind Kind) const {
749     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
750   }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const751   bool isDefaultmapCapturedByRef(unsigned Level,
752                                  OpenMPDefaultmapClauseKind Kind) const {
753     OpenMPDefaultmapClauseModifier M =
754         getDefaultmapModifierAtLevel(Level, Kind);
755     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
756       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
757              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
758              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
759              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
760     }
761     return true;
762   }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)763   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
764                                      OpenMPDefaultmapClauseKind Kind) {
765     switch (Kind) {
766     case OMPC_DEFAULTMAP_scalar:
767     case OMPC_DEFAULTMAP_pointer:
768       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
769              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
770              (M == OMPC_DEFAULTMAP_MODIFIER_default);
771     case OMPC_DEFAULTMAP_aggregate:
772       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
773     default:
774       break;
775     }
776     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
777   }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const778   bool mustBeFirstprivateAtLevel(unsigned Level,
779                                  OpenMPDefaultmapClauseKind Kind) const {
780     OpenMPDefaultmapClauseModifier M =
781         getDefaultmapModifierAtLevel(Level, Kind);
782     return mustBeFirstprivateBase(M, Kind);
783   }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const784   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
785     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
786     return mustBeFirstprivateBase(M, Kind);
787   }
788 
789   /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)790   bool isThreadPrivate(VarDecl *D) {
791     const DSAVarData DVar = getTopDSA(D, false);
792     return isOpenMPThreadPrivate(DVar.CKind);
793   }
794 
795   /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)796   void setOrderedRegion(bool IsOrdered, const Expr *Param,
797                         OMPOrderedClause *Clause) {
798     if (IsOrdered)
799       getTopOfStack().OrderedRegion.emplace(Param, Clause);
800     else
801       getTopOfStack().OrderedRegion.reset();
802   }
803   /// Returns true, if region is ordered (has associated 'ordered' clause),
804   /// false - otherwise.
isOrderedRegion() const805   bool isOrderedRegion() const {
806     if (const SharingMapTy *Top = getTopOfStackOrNull())
807       return Top->OrderedRegion.hasValue();
808     return false;
809   }
810   /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const811   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
812     if (const SharingMapTy *Top = getTopOfStackOrNull())
813       if (Top->OrderedRegion.hasValue())
814         return Top->OrderedRegion.getValue();
815     return std::make_pair(nullptr, nullptr);
816   }
817   /// Returns true, if parent region is ordered (has associated
818   /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const819   bool isParentOrderedRegion() const {
820     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
821       return Parent->OrderedRegion.hasValue();
822     return false;
823   }
824   /// Returns optional parameter for the ordered region.
825   std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const826   getParentOrderedRegionParam() const {
827     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
828       if (Parent->OrderedRegion.hasValue())
829         return Parent->OrderedRegion.getValue();
830     return std::make_pair(nullptr, nullptr);
831   }
832   /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)833   void setNowaitRegion(bool IsNowait = true) {
834     getTopOfStack().NowaitRegion = IsNowait;
835   }
836   /// Returns true, if parent region is nowait (has associated
837   /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const838   bool isParentNowaitRegion() const {
839     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840       return Parent->NowaitRegion;
841     return false;
842   }
843   /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)844   void setParentCancelRegion(bool Cancel = true) {
845     if (SharingMapTy *Parent = getSecondOnStackOrNull())
846       Parent->CancelRegion |= Cancel;
847   }
848   /// Return true if current region has inner cancel construct.
isCancelRegion() const849   bool isCancelRegion() const {
850     const SharingMapTy *Top = getTopOfStackOrNull();
851     return Top ? Top->CancelRegion : false;
852   }
853 
854   /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)855   void setParentHasScanDirective(SourceLocation Loc) {
856     if (SharingMapTy *Parent = getSecondOnStackOrNull())
857       Parent->PrevScanLocation = Loc;
858   }
859   /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const860   bool doesParentHasScanDirective() const {
861     const SharingMapTy *Top = getSecondOnStackOrNull();
862     return Top ? Top->PrevScanLocation.isValid() : false;
863   }
864   /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const865   SourceLocation getParentScanDirectiveLoc() const {
866     const SharingMapTy *Top = getSecondOnStackOrNull();
867     return Top ? Top->PrevScanLocation : SourceLocation();
868   }
869   /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)870   void setParentHasOrderedDirective(SourceLocation Loc) {
871     if (SharingMapTy *Parent = getSecondOnStackOrNull())
872       Parent->PrevOrderedLocation = Loc;
873   }
874   /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const875   bool doesParentHasOrderedDirective() const {
876     const SharingMapTy *Top = getSecondOnStackOrNull();
877     return Top ? Top->PrevOrderedLocation.isValid() : false;
878   }
879   /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const880   SourceLocation getParentOrderedDirectiveLoc() const {
881     const SharingMapTy *Top = getSecondOnStackOrNull();
882     return Top ? Top->PrevOrderedLocation : SourceLocation();
883   }
884 
885   /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)886   void setAssociatedLoops(unsigned Val) {
887     getTopOfStack().AssociatedLoops = Val;
888     if (Val > 1)
889       getTopOfStack().HasMutipleLoops = true;
890   }
891   /// Return collapse value for region.
getAssociatedLoops() const892   unsigned getAssociatedLoops() const {
893     const SharingMapTy *Top = getTopOfStackOrNull();
894     return Top ? Top->AssociatedLoops : 0;
895   }
896   /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const897   bool hasMutipleLoops() const {
898     const SharingMapTy *Top = getTopOfStackOrNull();
899     return Top ? Top->HasMutipleLoops : false;
900   }
901 
902   /// Marks current target region as one with closely nested teams
903   /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)904   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
905     if (SharingMapTy *Parent = getSecondOnStackOrNull())
906       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
907   }
908   /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const909   bool hasInnerTeamsRegion() const {
910     return getInnerTeamsRegionLoc().isValid();
911   }
912   /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const913   SourceLocation getInnerTeamsRegionLoc() const {
914     const SharingMapTy *Top = getTopOfStackOrNull();
915     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
916   }
917 
getCurScope() const918   Scope *getCurScope() const {
919     const SharingMapTy *Top = getTopOfStackOrNull();
920     return Top ? Top->CurScope : nullptr;
921   }
setContext(DeclContext * DC)922   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const923   SourceLocation getConstructLoc() const {
924     const SharingMapTy *Top = getTopOfStackOrNull();
925     return Top ? Top->ConstructLoc : SourceLocation();
926   }
927 
928   /// Do the check specified in \a Check to all component lists and return true
929   /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const930   bool checkMappableExprComponentListsForDecl(
931       const ValueDecl *VD, bool CurrentRegionOnly,
932       const llvm::function_ref<
933           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
934                OpenMPClauseKind)>
935           Check) const {
936     if (isStackEmpty())
937       return false;
938     auto SI = begin();
939     auto SE = end();
940 
941     if (SI == SE)
942       return false;
943 
944     if (CurrentRegionOnly)
945       SE = std::next(SI);
946     else
947       std::advance(SI, 1);
948 
949     for (; SI != SE; ++SI) {
950       auto MI = SI->MappedExprComponents.find(VD);
951       if (MI != SI->MappedExprComponents.end())
952         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
953              MI->second.Components)
954           if (Check(L, MI->second.Kind))
955             return true;
956     }
957     return false;
958   }
959 
960   /// Do the check specified in \a Check to all component lists at a given level
961   /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const962   bool checkMappableExprComponentListsForDeclAtLevel(
963       const ValueDecl *VD, unsigned Level,
964       const llvm::function_ref<
965           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
966                OpenMPClauseKind)>
967           Check) const {
968     if (getStackSize() <= Level)
969       return false;
970 
971     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
972     auto MI = StackElem.MappedExprComponents.find(VD);
973     if (MI != StackElem.MappedExprComponents.end())
974       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
975            MI->second.Components)
976         if (Check(L, MI->second.Kind))
977           return true;
978     return false;
979   }
980 
981   /// Create a new mappable expression component list associated with a given
982   /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)983   void addMappableExpressionComponents(
984       const ValueDecl *VD,
985       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
986       OpenMPClauseKind WhereFoundClauseKind) {
987     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
988     // Create new entry and append the new components there.
989     MEC.Components.resize(MEC.Components.size() + 1);
990     MEC.Components.back().append(Components.begin(), Components.end());
991     MEC.Kind = WhereFoundClauseKind;
992   }
993 
getNestingLevel() const994   unsigned getNestingLevel() const {
995     assert(!isStackEmpty());
996     return getStackSize() - 1;
997   }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)998   void addDoacrossDependClause(OMPDependClause *C,
999                                const OperatorOffsetTy &OpsOffs) {
1000     SharingMapTy *Parent = getSecondOnStackOrNull();
1001     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1002     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1003   }
1004   llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const1005   getDoacrossDependClauses() const {
1006     const SharingMapTy &StackElem = getTopOfStack();
1007     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1008       const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1009       return llvm::make_range(Ref.begin(), Ref.end());
1010     }
1011     return llvm::make_range(StackElem.DoacrossDepends.end(),
1012                             StackElem.DoacrossDepends.end());
1013   }
1014 
1015   // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1016   void addMappedClassesQualTypes(QualType QT) {
1017     SharingMapTy &StackElem = getTopOfStack();
1018     StackElem.MappedClassesQualTypes.insert(QT);
1019   }
1020 
1021   // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1022   bool isClassPreviouslyMapped(QualType QT) const {
1023     const SharingMapTy &StackElem = getTopOfStack();
1024     return StackElem.MappedClassesQualTypes.count(QT) != 0;
1025   }
1026 
1027   /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1028   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1029     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1030                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1031            "Expected declare target link global.");
1032     for (auto &Elem : *this) {
1033       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1034         Elem.DeclareTargetLinkVarDecls.push_back(E);
1035         return;
1036       }
1037     }
1038   }
1039 
1040   /// Returns the list of globals with declare target link if current directive
1041   /// is target.
getLinkGlobals() const1042   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1043     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1044            "Expected target executable directive.");
1045     return getTopOfStack().DeclareTargetLinkVarDecls;
1046   }
1047 
1048   /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1049   void addInnerAllocatorExpr(Expr *E) {
1050     getTopOfStack().InnerUsedAllocators.push_back(E);
1051   }
1052   /// Return list of used allocators.
getInnerAllocators() const1053   ArrayRef<Expr *> getInnerAllocators() const {
1054     return getTopOfStack().InnerUsedAllocators;
1055   }
1056   /// Marks the declaration as implicitly firstprivate nin the task-based
1057   /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1058   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1059     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1060   }
1061   /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1062   bool isImplicitTaskFirstprivate(Decl *D) const {
1063     return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1064   }
1065 
1066   /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1067   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1068     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1069   }
1070   /// Checks if specified decl is used in uses allocator clause as the
1071   /// allocator.
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1072   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1073                                                         const Decl *D) const {
1074     const SharingMapTy &StackElem = getTopOfStack();
1075     auto I = StackElem.UsesAllocatorsDecls.find(D);
1076     if (I == StackElem.UsesAllocatorsDecls.end())
1077       return None;
1078     return I->getSecond();
1079   }
isUsesAllocatorsDecl(const Decl * D) const1080   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1081     const SharingMapTy &StackElem = getTopOfStack();
1082     auto I = StackElem.UsesAllocatorsDecls.find(D);
1083     if (I == StackElem.UsesAllocatorsDecls.end())
1084       return None;
1085     return I->getSecond();
1086   }
1087 
addDeclareMapperVarRef(Expr * Ref)1088   void addDeclareMapperVarRef(Expr *Ref) {
1089     SharingMapTy &StackElem = getTopOfStack();
1090     StackElem.DeclareMapperVar = Ref;
1091   }
getDeclareMapperVarRef() const1092   const Expr *getDeclareMapperVarRef() const {
1093     const SharingMapTy *Top = getTopOfStackOrNull();
1094     return Top ? Top->DeclareMapperVar : nullptr;
1095   }
1096 };
1097 
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1098 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1099   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1100 }
1101 
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1102 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1103   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1104          DKind == OMPD_unknown;
1105 }
1106 
1107 } // namespace
1108 
getExprAsWritten(const Expr * E)1109 static const Expr *getExprAsWritten(const Expr *E) {
1110   if (const auto *FE = dyn_cast<FullExpr>(E))
1111     E = FE->getSubExpr();
1112 
1113   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1114     E = MTE->getSubExpr();
1115 
1116   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1117     E = Binder->getSubExpr();
1118 
1119   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1120     E = ICE->getSubExprAsWritten();
1121   return E->IgnoreParens();
1122 }
1123 
getExprAsWritten(Expr * E)1124 static Expr *getExprAsWritten(Expr *E) {
1125   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1126 }
1127 
getCanonicalDecl(const ValueDecl * D)1128 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1129   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1130     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1131       D = ME->getMemberDecl();
1132   const auto *VD = dyn_cast<VarDecl>(D);
1133   const auto *FD = dyn_cast<FieldDecl>(D);
1134   if (VD != nullptr) {
1135     VD = VD->getCanonicalDecl();
1136     D = VD;
1137   } else {
1138     assert(FD);
1139     FD = FD->getCanonicalDecl();
1140     D = FD;
1141   }
1142   return D;
1143 }
1144 
getCanonicalDecl(ValueDecl * D)1145 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1146   return const_cast<ValueDecl *>(
1147       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1148 }
1149 
getDSA(const_iterator & Iter,ValueDecl * D) const1150 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1151                                           ValueDecl *D) const {
1152   D = getCanonicalDecl(D);
1153   auto *VD = dyn_cast<VarDecl>(D);
1154   const auto *FD = dyn_cast<FieldDecl>(D);
1155   DSAVarData DVar;
1156   if (Iter == end()) {
1157     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1158     // in a region but not in construct]
1159     //  File-scope or namespace-scope variables referenced in called routines
1160     //  in the region are shared unless they appear in a threadprivate
1161     //  directive.
1162     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1163       DVar.CKind = OMPC_shared;
1164 
1165     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1166     // in a region but not in construct]
1167     //  Variables with static storage duration that are declared in called
1168     //  routines in the region are shared.
1169     if (VD && VD->hasGlobalStorage())
1170       DVar.CKind = OMPC_shared;
1171 
1172     // Non-static data members are shared by default.
1173     if (FD)
1174       DVar.CKind = OMPC_shared;
1175 
1176     return DVar;
1177   }
1178 
1179   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1180   // in a Construct, C/C++, predetermined, p.1]
1181   // Variables with automatic storage duration that are declared in a scope
1182   // inside the construct are private.
1183   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1184       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1185     DVar.CKind = OMPC_private;
1186     return DVar;
1187   }
1188 
1189   DVar.DKind = Iter->Directive;
1190   // Explicitly specified attributes and local variables with predetermined
1191   // attributes.
1192   if (Iter->SharingMap.count(D)) {
1193     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1194     DVar.RefExpr = Data.RefExpr.getPointer();
1195     DVar.PrivateCopy = Data.PrivateCopy;
1196     DVar.CKind = Data.Attributes;
1197     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1198     DVar.Modifier = Data.Modifier;
1199     DVar.AppliedToPointee = Data.AppliedToPointee;
1200     return DVar;
1201   }
1202 
1203   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1204   // in a Construct, C/C++, implicitly determined, p.1]
1205   //  In a parallel or task construct, the data-sharing attributes of these
1206   //  variables are determined by the default clause, if present.
1207   switch (Iter->DefaultAttr) {
1208   case DSA_shared:
1209     DVar.CKind = OMPC_shared;
1210     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1211     return DVar;
1212   case DSA_none:
1213     return DVar;
1214   case DSA_firstprivate:
1215     if (VD->getStorageDuration() == SD_Static &&
1216         VD->getDeclContext()->isFileContext()) {
1217       DVar.CKind = OMPC_unknown;
1218     } else {
1219       DVar.CKind = OMPC_firstprivate;
1220     }
1221     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1222     return DVar;
1223   case DSA_unspecified:
1224     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1225     // in a Construct, implicitly determined, p.2]
1226     //  In a parallel construct, if no default clause is present, these
1227     //  variables are shared.
1228     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1229     if ((isOpenMPParallelDirective(DVar.DKind) &&
1230          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1231         isOpenMPTeamsDirective(DVar.DKind)) {
1232       DVar.CKind = OMPC_shared;
1233       return DVar;
1234     }
1235 
1236     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1237     // in a Construct, implicitly determined, p.4]
1238     //  In a task construct, if no default clause is present, a variable that in
1239     //  the enclosing context is determined to be shared by all implicit tasks
1240     //  bound to the current team is shared.
1241     if (isOpenMPTaskingDirective(DVar.DKind)) {
1242       DSAVarData DVarTemp;
1243       const_iterator I = Iter, E = end();
1244       do {
1245         ++I;
1246         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1247         // Referenced in a Construct, implicitly determined, p.6]
1248         //  In a task construct, if no default clause is present, a variable
1249         //  whose data-sharing attribute is not determined by the rules above is
1250         //  firstprivate.
1251         DVarTemp = getDSA(I, D);
1252         if (DVarTemp.CKind != OMPC_shared) {
1253           DVar.RefExpr = nullptr;
1254           DVar.CKind = OMPC_firstprivate;
1255           return DVar;
1256         }
1257       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1258       DVar.CKind =
1259           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1260       return DVar;
1261     }
1262   }
1263   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1264   // in a Construct, implicitly determined, p.3]
1265   //  For constructs other than task, if no default clause is present, these
1266   //  variables inherit their data-sharing attributes from the enclosing
1267   //  context.
1268   return getDSA(++Iter, D);
1269 }
1270 
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1271 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1272                                          const Expr *NewDE) {
1273   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1274   D = getCanonicalDecl(D);
1275   SharingMapTy &StackElem = getTopOfStack();
1276   auto It = StackElem.AlignedMap.find(D);
1277   if (It == StackElem.AlignedMap.end()) {
1278     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1279     StackElem.AlignedMap[D] = NewDE;
1280     return nullptr;
1281   }
1282   assert(It->second && "Unexpected nullptr expr in the aligned map");
1283   return It->second;
1284 }
1285 
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1286 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1287                                              const Expr *NewDE) {
1288   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1289   D = getCanonicalDecl(D);
1290   SharingMapTy &StackElem = getTopOfStack();
1291   auto It = StackElem.NontemporalMap.find(D);
1292   if (It == StackElem.NontemporalMap.end()) {
1293     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1294     StackElem.NontemporalMap[D] = NewDE;
1295     return nullptr;
1296   }
1297   assert(It->second && "Unexpected nullptr expr in the aligned map");
1298   return It->second;
1299 }
1300 
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1301 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1302   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1303   D = getCanonicalDecl(D);
1304   SharingMapTy &StackElem = getTopOfStack();
1305   StackElem.LCVMap.try_emplace(
1306       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1307 }
1308 
1309 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1310 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1311   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1312   D = getCanonicalDecl(D);
1313   const SharingMapTy &StackElem = getTopOfStack();
1314   auto It = StackElem.LCVMap.find(D);
1315   if (It != StackElem.LCVMap.end())
1316     return It->second;
1317   return {0, nullptr};
1318 }
1319 
1320 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1321 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1322   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1323   D = getCanonicalDecl(D);
1324   for (unsigned I = Level + 1; I > 0; --I) {
1325     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1326     auto It = StackElem.LCVMap.find(D);
1327     if (It != StackElem.LCVMap.end())
1328       return It->second;
1329   }
1330   return {0, nullptr};
1331 }
1332 
1333 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1334 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1335   const SharingMapTy *Parent = getSecondOnStackOrNull();
1336   assert(Parent && "Data-sharing attributes stack is empty");
1337   D = getCanonicalDecl(D);
1338   auto It = Parent->LCVMap.find(D);
1339   if (It != Parent->LCVMap.end())
1340     return It->second;
1341   return {0, nullptr};
1342 }
1343 
getParentLoopControlVariable(unsigned I) const1344 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1345   const SharingMapTy *Parent = getSecondOnStackOrNull();
1346   assert(Parent && "Data-sharing attributes stack is empty");
1347   if (Parent->LCVMap.size() < I)
1348     return nullptr;
1349   for (const auto &Pair : Parent->LCVMap)
1350     if (Pair.second.first == I)
1351       return Pair.first;
1352   return nullptr;
1353 }
1354 
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1355 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1356                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1357                         bool AppliedToPointee) {
1358   D = getCanonicalDecl(D);
1359   if (A == OMPC_threadprivate) {
1360     DSAInfo &Data = Threadprivates[D];
1361     Data.Attributes = A;
1362     Data.RefExpr.setPointer(E);
1363     Data.PrivateCopy = nullptr;
1364     Data.Modifier = Modifier;
1365   } else {
1366     DSAInfo &Data = getTopOfStack().SharingMap[D];
1367     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1368            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1369            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1370            (isLoopControlVariable(D).first && A == OMPC_private));
1371     Data.Modifier = Modifier;
1372     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1373       Data.RefExpr.setInt(/*IntVal=*/true);
1374       return;
1375     }
1376     const bool IsLastprivate =
1377         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1378     Data.Attributes = A;
1379     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1380     Data.PrivateCopy = PrivateCopy;
1381     Data.AppliedToPointee = AppliedToPointee;
1382     if (PrivateCopy) {
1383       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1384       Data.Modifier = Modifier;
1385       Data.Attributes = A;
1386       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1387       Data.PrivateCopy = nullptr;
1388       Data.AppliedToPointee = AppliedToPointee;
1389     }
1390   }
1391 }
1392 
1393 /// 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)1394 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1395                              StringRef Name, const AttrVec *Attrs = nullptr,
1396                              DeclRefExpr *OrigRef = nullptr) {
1397   DeclContext *DC = SemaRef.CurContext;
1398   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1399   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1400   auto *Decl =
1401       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1402   if (Attrs) {
1403     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1404          I != E; ++I)
1405       Decl->addAttr(*I);
1406   }
1407   Decl->setImplicit();
1408   if (OrigRef) {
1409     Decl->addAttr(
1410         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1411   }
1412   return Decl;
1413 }
1414 
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1415 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1416                                      SourceLocation Loc,
1417                                      bool RefersToCapture = false) {
1418   D->setReferenced();
1419   D->markUsed(S.Context);
1420   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1421                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1422                              VK_LValue);
1423 }
1424 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1425 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1426                                            BinaryOperatorKind BOK) {
1427   D = getCanonicalDecl(D);
1428   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1429   assert(
1430       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1431       "Additional reduction info may be specified only for reduction items.");
1432   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1433   assert(ReductionData.ReductionRange.isInvalid() &&
1434          (getTopOfStack().Directive == OMPD_taskgroup ||
1435           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1436             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1437            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1438          "Additional reduction info may be specified only once for reduction "
1439          "items.");
1440   ReductionData.set(BOK, SR);
1441   Expr *&TaskgroupReductionRef =
1442       getTopOfStack().TaskgroupReductionRef;
1443   if (!TaskgroupReductionRef) {
1444     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1445                                SemaRef.Context.VoidPtrTy, ".task_red.");
1446     TaskgroupReductionRef =
1447         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1448   }
1449 }
1450 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1451 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1452                                            const Expr *ReductionRef) {
1453   D = getCanonicalDecl(D);
1454   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1455   assert(
1456       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1457       "Additional reduction info may be specified only for reduction items.");
1458   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1459   assert(ReductionData.ReductionRange.isInvalid() &&
1460          (getTopOfStack().Directive == OMPD_taskgroup ||
1461           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1462             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1463            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1464          "Additional reduction info may be specified only once for reduction "
1465          "items.");
1466   ReductionData.set(ReductionRef, SR);
1467   Expr *&TaskgroupReductionRef =
1468       getTopOfStack().TaskgroupReductionRef;
1469   if (!TaskgroupReductionRef) {
1470     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1471                                SemaRef.Context.VoidPtrTy, ".task_red.");
1472     TaskgroupReductionRef =
1473         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1474   }
1475 }
1476 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1477 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1478     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1479     Expr *&TaskgroupDescriptor) const {
1480   D = getCanonicalDecl(D);
1481   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1482   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1483     const DSAInfo &Data = I->SharingMap.lookup(D);
1484     if (Data.Attributes != OMPC_reduction ||
1485         Data.Modifier != OMPC_REDUCTION_task)
1486       continue;
1487     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1488     if (!ReductionData.ReductionOp ||
1489         ReductionData.ReductionOp.is<const Expr *>())
1490       return DSAVarData();
1491     SR = ReductionData.ReductionRange;
1492     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1493     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1494                                        "expression for the descriptor is not "
1495                                        "set.");
1496     TaskgroupDescriptor = I->TaskgroupReductionRef;
1497     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1498                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1499                       /*AppliedToPointee=*/false);
1500   }
1501   return DSAVarData();
1502 }
1503 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1504 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1505     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1506     Expr *&TaskgroupDescriptor) const {
1507   D = getCanonicalDecl(D);
1508   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1509   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1510     const DSAInfo &Data = I->SharingMap.lookup(D);
1511     if (Data.Attributes != OMPC_reduction ||
1512         Data.Modifier != OMPC_REDUCTION_task)
1513       continue;
1514     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1515     if (!ReductionData.ReductionOp ||
1516         !ReductionData.ReductionOp.is<const Expr *>())
1517       return DSAVarData();
1518     SR = ReductionData.ReductionRange;
1519     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1520     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1521                                        "expression for the descriptor is not "
1522                                        "set.");
1523     TaskgroupDescriptor = I->TaskgroupReductionRef;
1524     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1525                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1526                       /*AppliedToPointee=*/false);
1527   }
1528   return DSAVarData();
1529 }
1530 
isOpenMPLocal(VarDecl * D,const_iterator I) const1531 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1532   D = D->getCanonicalDecl();
1533   for (const_iterator E = end(); I != E; ++I) {
1534     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1535         isOpenMPTargetExecutionDirective(I->Directive)) {
1536       if (I->CurScope) {
1537         Scope *TopScope = I->CurScope->getParent();
1538         Scope *CurScope = getCurScope();
1539         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1540           CurScope = CurScope->getParent();
1541         return CurScope != TopScope;
1542       }
1543       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1544         if (I->Context == DC)
1545           return true;
1546       return false;
1547     }
1548   }
1549   return false;
1550 }
1551 
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1552 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1553                                   bool AcceptIfMutable = true,
1554                                   bool *IsClassType = nullptr) {
1555   ASTContext &Context = SemaRef.getASTContext();
1556   Type = Type.getNonReferenceType().getCanonicalType();
1557   bool IsConstant = Type.isConstant(Context);
1558   Type = Context.getBaseElementType(Type);
1559   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1560                                 ? Type->getAsCXXRecordDecl()
1561                                 : nullptr;
1562   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1563     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1564       RD = CTD->getTemplatedDecl();
1565   if (IsClassType)
1566     *IsClassType = RD;
1567   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1568                          RD->hasDefinition() && RD->hasMutableFields());
1569 }
1570 
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1571 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1572                                       QualType Type, OpenMPClauseKind CKind,
1573                                       SourceLocation ELoc,
1574                                       bool AcceptIfMutable = true,
1575                                       bool ListItemNotVar = false) {
1576   ASTContext &Context = SemaRef.getASTContext();
1577   bool IsClassType;
1578   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1579     unsigned Diag = ListItemNotVar
1580                         ? diag::err_omp_const_list_item
1581                         : IsClassType ? diag::err_omp_const_not_mutable_variable
1582                                       : diag::err_omp_const_variable;
1583     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1584     if (!ListItemNotVar && D) {
1585       const VarDecl *VD = dyn_cast<VarDecl>(D);
1586       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1587                                VarDecl::DeclarationOnly;
1588       SemaRef.Diag(D->getLocation(),
1589                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1590           << D;
1591     }
1592     return true;
1593   }
1594   return false;
1595 }
1596 
getTopDSA(ValueDecl * D,bool FromParent)1597 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1598                                                    bool FromParent) {
1599   D = getCanonicalDecl(D);
1600   DSAVarData DVar;
1601 
1602   auto *VD = dyn_cast<VarDecl>(D);
1603   auto TI = Threadprivates.find(D);
1604   if (TI != Threadprivates.end()) {
1605     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1606     DVar.CKind = OMPC_threadprivate;
1607     DVar.Modifier = TI->getSecond().Modifier;
1608     return DVar;
1609   }
1610   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1611     DVar.RefExpr = buildDeclRefExpr(
1612         SemaRef, VD, D->getType().getNonReferenceType(),
1613         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1614     DVar.CKind = OMPC_threadprivate;
1615     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1616     return DVar;
1617   }
1618   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1619   // in a Construct, C/C++, predetermined, p.1]
1620   //  Variables appearing in threadprivate directives are threadprivate.
1621   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1622        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1623          SemaRef.getLangOpts().OpenMPUseTLS &&
1624          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1625       (VD && VD->getStorageClass() == SC_Register &&
1626        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1627     DVar.RefExpr = buildDeclRefExpr(
1628         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1629     DVar.CKind = OMPC_threadprivate;
1630     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1631     return DVar;
1632   }
1633   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1634       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1635       !isLoopControlVariable(D).first) {
1636     const_iterator IterTarget =
1637         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1638           return isOpenMPTargetExecutionDirective(Data.Directive);
1639         });
1640     if (IterTarget != end()) {
1641       const_iterator ParentIterTarget = IterTarget + 1;
1642       for (const_iterator Iter = begin();
1643            Iter != ParentIterTarget; ++Iter) {
1644         if (isOpenMPLocal(VD, Iter)) {
1645           DVar.RefExpr =
1646               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1647                                D->getLocation());
1648           DVar.CKind = OMPC_threadprivate;
1649           return DVar;
1650         }
1651       }
1652       if (!isClauseParsingMode() || IterTarget != begin()) {
1653         auto DSAIter = IterTarget->SharingMap.find(D);
1654         if (DSAIter != IterTarget->SharingMap.end() &&
1655             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1656           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1657           DVar.CKind = OMPC_threadprivate;
1658           return DVar;
1659         }
1660         const_iterator End = end();
1661         if (!SemaRef.isOpenMPCapturedByRef(
1662                 D, std::distance(ParentIterTarget, End),
1663                 /*OpenMPCaptureLevel=*/0)) {
1664           DVar.RefExpr =
1665               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1666                                IterTarget->ConstructLoc);
1667           DVar.CKind = OMPC_threadprivate;
1668           return DVar;
1669         }
1670       }
1671     }
1672   }
1673 
1674   if (isStackEmpty())
1675     // Not in OpenMP execution region and top scope was already checked.
1676     return DVar;
1677 
1678   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1679   // in a Construct, C/C++, predetermined, p.4]
1680   //  Static data members are shared.
1681   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1682   // in a Construct, C/C++, predetermined, p.7]
1683   //  Variables with static storage duration that are declared in a scope
1684   //  inside the construct are shared.
1685   if (VD && VD->isStaticDataMember()) {
1686     // Check for explicitly specified attributes.
1687     const_iterator I = begin();
1688     const_iterator EndI = end();
1689     if (FromParent && I != EndI)
1690       ++I;
1691     if (I != EndI) {
1692       auto It = I->SharingMap.find(D);
1693       if (It != I->SharingMap.end()) {
1694         const DSAInfo &Data = It->getSecond();
1695         DVar.RefExpr = Data.RefExpr.getPointer();
1696         DVar.PrivateCopy = Data.PrivateCopy;
1697         DVar.CKind = Data.Attributes;
1698         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1699         DVar.DKind = I->Directive;
1700         DVar.Modifier = Data.Modifier;
1701         DVar.AppliedToPointee = Data.AppliedToPointee;
1702         return DVar;
1703       }
1704     }
1705 
1706     DVar.CKind = OMPC_shared;
1707     return DVar;
1708   }
1709 
1710   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1711   // The predetermined shared attribute for const-qualified types having no
1712   // mutable members was removed after OpenMP 3.1.
1713   if (SemaRef.LangOpts.OpenMP <= 31) {
1714     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1715     // in a Construct, C/C++, predetermined, p.6]
1716     //  Variables with const qualified type having no mutable member are
1717     //  shared.
1718     if (isConstNotMutableType(SemaRef, D->getType())) {
1719       // Variables with const-qualified type having no mutable member may be
1720       // listed in a firstprivate clause, even if they are static data members.
1721       DSAVarData DVarTemp = hasInnermostDSA(
1722           D,
1723           [](OpenMPClauseKind C, bool) {
1724             return C == OMPC_firstprivate || C == OMPC_shared;
1725           },
1726           MatchesAlways, FromParent);
1727       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1728         return DVarTemp;
1729 
1730       DVar.CKind = OMPC_shared;
1731       return DVar;
1732     }
1733   }
1734 
1735   // Explicitly specified attributes and local variables with predetermined
1736   // attributes.
1737   const_iterator I = begin();
1738   const_iterator EndI = end();
1739   if (FromParent && I != EndI)
1740     ++I;
1741   if (I == EndI)
1742     return DVar;
1743   auto It = I->SharingMap.find(D);
1744   if (It != I->SharingMap.end()) {
1745     const DSAInfo &Data = It->getSecond();
1746     DVar.RefExpr = Data.RefExpr.getPointer();
1747     DVar.PrivateCopy = Data.PrivateCopy;
1748     DVar.CKind = Data.Attributes;
1749     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1750     DVar.DKind = I->Directive;
1751     DVar.Modifier = Data.Modifier;
1752     DVar.AppliedToPointee = Data.AppliedToPointee;
1753   }
1754 
1755   return DVar;
1756 }
1757 
getImplicitDSA(ValueDecl * D,bool FromParent) const1758 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1759                                                         bool FromParent) const {
1760   if (isStackEmpty()) {
1761     const_iterator I;
1762     return getDSA(I, D);
1763   }
1764   D = getCanonicalDecl(D);
1765   const_iterator StartI = begin();
1766   const_iterator EndI = end();
1767   if (FromParent && StartI != EndI)
1768     ++StartI;
1769   return getDSA(StartI, D);
1770 }
1771 
getImplicitDSA(ValueDecl * D,unsigned Level) const1772 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1773                                                         unsigned Level) const {
1774   if (getStackSize() <= Level)
1775     return DSAVarData();
1776   D = getCanonicalDecl(D);
1777   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1778   return getDSA(StartI, D);
1779 }
1780 
1781 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1782 DSAStackTy::hasDSA(ValueDecl *D,
1783                    const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1784                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1785                    bool FromParent) const {
1786   if (isStackEmpty())
1787     return {};
1788   D = getCanonicalDecl(D);
1789   const_iterator I = begin();
1790   const_iterator EndI = end();
1791   if (FromParent && I != EndI)
1792     ++I;
1793   for (; I != EndI; ++I) {
1794     if (!DPred(I->Directive) &&
1795         !isImplicitOrExplicitTaskingRegion(I->Directive))
1796       continue;
1797     const_iterator NewI = I;
1798     DSAVarData DVar = getDSA(NewI, D);
1799     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1800       return DVar;
1801   }
1802   return {};
1803 }
1804 
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1805 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1806     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1807     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1808     bool FromParent) const {
1809   if (isStackEmpty())
1810     return {};
1811   D = getCanonicalDecl(D);
1812   const_iterator StartI = begin();
1813   const_iterator EndI = end();
1814   if (FromParent && StartI != EndI)
1815     ++StartI;
1816   if (StartI == EndI || !DPred(StartI->Directive))
1817     return {};
1818   const_iterator NewI = StartI;
1819   DSAVarData DVar = getDSA(NewI, D);
1820   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1821              ? DVar
1822              : DSAVarData();
1823 }
1824 
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1825 bool DSAStackTy::hasExplicitDSA(
1826     const ValueDecl *D,
1827     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1828     unsigned Level, bool NotLastprivate) const {
1829   if (getStackSize() <= Level)
1830     return false;
1831   D = getCanonicalDecl(D);
1832   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1833   auto I = StackElem.SharingMap.find(D);
1834   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1835       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1836       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1837     return true;
1838   // Check predetermined rules for the loop control variables.
1839   auto LI = StackElem.LCVMap.find(D);
1840   if (LI != StackElem.LCVMap.end())
1841     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1842   return false;
1843 }
1844 
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1845 bool DSAStackTy::hasExplicitDirective(
1846     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1847     unsigned Level) const {
1848   if (getStackSize() <= Level)
1849     return false;
1850   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1851   return DPred(StackElem.Directive);
1852 }
1853 
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1854 bool DSAStackTy::hasDirective(
1855     const llvm::function_ref<bool(OpenMPDirectiveKind,
1856                                   const DeclarationNameInfo &, SourceLocation)>
1857         DPred,
1858     bool FromParent) const {
1859   // We look only in the enclosing region.
1860   size_t Skip = FromParent ? 2 : 1;
1861   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1862        I != E; ++I) {
1863     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1864       return true;
1865   }
1866   return false;
1867 }
1868 
InitDataSharingAttributesStack()1869 void Sema::InitDataSharingAttributesStack() {
1870   VarDataSharingAttributesStack = new DSAStackTy(*this);
1871 }
1872 
1873 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1874 
pushOpenMPFunctionRegion()1875 void Sema::pushOpenMPFunctionRegion() {
1876   DSAStack->pushFunction();
1877 }
1878 
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1879 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1880   DSAStack->popFunction(OldFSI);
1881 }
1882 
isOpenMPDeviceDelayedContext(Sema & S)1883 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1884   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1885          "Expected OpenMP device compilation.");
1886   return !S.isInOpenMPTargetExecutionDirective() &&
1887          !S.isInOpenMPDeclareTargetContext();
1888 }
1889 
1890 namespace {
1891 /// Status of the function emission on the host/device.
1892 enum class FunctionEmissionStatus {
1893   Emitted,
1894   Discarded,
1895   Unknown,
1896 };
1897 } // anonymous namespace
1898 
diagIfOpenMPDeviceCode(SourceLocation Loc,unsigned DiagID)1899 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900                                                          unsigned DiagID) {
1901   assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1902          "Expected OpenMP device compilation.");
1903 
1904   FunctionDecl *FD = getCurFunctionDecl();
1905   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1906   if (FD) {
1907     FunctionEmissionStatus FES = getEmissionStatus(FD);
1908     switch (FES) {
1909     case FunctionEmissionStatus::Emitted:
1910       Kind = SemaDiagnosticBuilder::K_Immediate;
1911       break;
1912     case FunctionEmissionStatus::Unknown:
1913       Kind = isOpenMPDeviceDelayedContext(*this)
1914                  ? SemaDiagnosticBuilder::K_Deferred
1915                  : SemaDiagnosticBuilder::K_Immediate;
1916       break;
1917     case FunctionEmissionStatus::TemplateDiscarded:
1918     case FunctionEmissionStatus::OMPDiscarded:
1919       Kind = SemaDiagnosticBuilder::K_Nop;
1920       break;
1921     case FunctionEmissionStatus::CUDADiscarded:
1922       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1923       break;
1924     }
1925   }
1926 
1927   return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1928 }
1929 
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID)1930 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1931                                                        unsigned DiagID) {
1932   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1933          "Expected OpenMP host compilation.");
1934   FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1935   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1936   switch (FES) {
1937   case FunctionEmissionStatus::Emitted:
1938     Kind = SemaDiagnosticBuilder::K_Immediate;
1939     break;
1940   case FunctionEmissionStatus::Unknown:
1941     Kind = SemaDiagnosticBuilder::K_Deferred;
1942     break;
1943   case FunctionEmissionStatus::TemplateDiscarded:
1944   case FunctionEmissionStatus::OMPDiscarded:
1945   case FunctionEmissionStatus::CUDADiscarded:
1946     Kind = SemaDiagnosticBuilder::K_Nop;
1947     break;
1948   }
1949 
1950   return SemaDiagnosticBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1951 }
1952 
1953 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)1954 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1955   if (LO.OpenMP <= 45) {
1956     if (VD->getType().getNonReferenceType()->isScalarType())
1957       return OMPC_DEFAULTMAP_scalar;
1958     return OMPC_DEFAULTMAP_aggregate;
1959   }
1960   if (VD->getType().getNonReferenceType()->isAnyPointerType())
1961     return OMPC_DEFAULTMAP_pointer;
1962   if (VD->getType().getNonReferenceType()->isScalarType())
1963     return OMPC_DEFAULTMAP_scalar;
1964   return OMPC_DEFAULTMAP_aggregate;
1965 }
1966 
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const1967 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1968                                  unsigned OpenMPCaptureLevel) const {
1969   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1970 
1971   ASTContext &Ctx = getASTContext();
1972   bool IsByRef = true;
1973 
1974   // Find the directive that is associated with the provided scope.
1975   D = cast<ValueDecl>(D->getCanonicalDecl());
1976   QualType Ty = D->getType();
1977 
1978   bool IsVariableUsedInMapClause = false;
1979   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1980     // This table summarizes how a given variable should be passed to the device
1981     // given its type and the clauses where it appears. This table is based on
1982     // the description in OpenMP 4.5 [2.10.4, target Construct] and
1983     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1984     //
1985     // =========================================================================
1986     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
1987     // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
1988     // =========================================================================
1989     // | scl  |               |     |       |       -       |          | bycopy|
1990     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
1991     // | scl  |               |  x  |   -   |       -       |     -    | null  |
1992     // | scl  |       x       |     |       |       -       |          | byref |
1993     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
1994     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
1995     // | scl  |               |  -  |   -   |       -       |     x    | byref |
1996     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
1997     //
1998     // | agg  |      n.a.     |     |       |       -       |          | byref |
1999     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2000     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2001     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2002     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2003     //
2004     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2005     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2006     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2007     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2008     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2009     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2010     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2011     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2012     // =========================================================================
2013     // Legend:
2014     //  scl - scalar
2015     //  ptr - pointer
2016     //  agg - aggregate
2017     //  x - applies
2018     //  - - invalid in this combination
2019     //  [] - mapped with an array section
2020     //  byref - should be mapped by reference
2021     //  byval - should be mapped by value
2022     //  null - initialize a local variable to null on the device
2023     //
2024     // Observations:
2025     //  - All scalar declarations that show up in a map clause have to be passed
2026     //    by reference, because they may have been mapped in the enclosing data
2027     //    environment.
2028     //  - If the scalar value does not fit the size of uintptr, it has to be
2029     //    passed by reference, regardless the result in the table above.
2030     //  - For pointers mapped by value that have either an implicit map or an
2031     //    array section, the runtime library may pass the NULL value to the
2032     //    device instead of the value passed to it by the compiler.
2033 
2034     if (Ty->isReferenceType())
2035       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2036 
2037     // Locate map clauses and see if the variable being captured is referred to
2038     // in any of those clauses. Here we only care about variables, not fields,
2039     // because fields are part of aggregates.
2040     bool IsVariableAssociatedWithSection = false;
2041 
2042     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2043         D, Level,
2044         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2045             OMPClauseMappableExprCommon::MappableExprComponentListRef
2046                 MapExprComponents,
2047             OpenMPClauseKind WhereFoundClauseKind) {
2048           // Only the map clause information influences how a variable is
2049           // captured. E.g. is_device_ptr does not require changing the default
2050           // behavior.
2051           if (WhereFoundClauseKind != OMPC_map)
2052             return false;
2053 
2054           auto EI = MapExprComponents.rbegin();
2055           auto EE = MapExprComponents.rend();
2056 
2057           assert(EI != EE && "Invalid map expression!");
2058 
2059           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2060             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2061 
2062           ++EI;
2063           if (EI == EE)
2064             return false;
2065 
2066           if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2067               isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2068               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2069               isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2070             IsVariableAssociatedWithSection = true;
2071             // There is nothing more we need to know about this variable.
2072             return true;
2073           }
2074 
2075           // Keep looking for more map info.
2076           return false;
2077         });
2078 
2079     if (IsVariableUsedInMapClause) {
2080       // If variable is identified in a map clause it is always captured by
2081       // reference except if it is a pointer that is dereferenced somehow.
2082       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2083     } else {
2084       // By default, all the data that has a scalar type is mapped by copy
2085       // (except for reduction variables).
2086       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2087       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2088                  !Ty->isAnyPointerType()) ||
2089                 !Ty->isScalarType() ||
2090                 DSAStack->isDefaultmapCapturedByRef(
2091                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2092                 DSAStack->hasExplicitDSA(
2093                     D,
2094                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2095                       return K == OMPC_reduction && !AppliedToPointee;
2096                     },
2097                     Level);
2098     }
2099   }
2100 
2101   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2102     IsByRef =
2103         ((IsVariableUsedInMapClause &&
2104           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2105               OMPD_target) ||
2106          !(DSAStack->hasExplicitDSA(
2107                D,
2108                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2109                  return K == OMPC_firstprivate ||
2110                         (K == OMPC_reduction && AppliedToPointee);
2111                },
2112                Level, /*NotLastprivate=*/true) ||
2113            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2114         // If the variable is artificial and must be captured by value - try to
2115         // capture by value.
2116         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2117           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2118         // If the variable is implicitly firstprivate and scalar - capture by
2119         // copy
2120         !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2121           !DSAStack->hasExplicitDSA(
2122               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2123               Level) &&
2124           !DSAStack->isLoopControlVariable(D, Level).first);
2125   }
2126 
2127   // When passing data by copy, we need to make sure it fits the uintptr size
2128   // and alignment, because the runtime library only deals with uintptr types.
2129   // If it does not fit the uintptr size, we need to pass the data by reference
2130   // instead.
2131   if (!IsByRef &&
2132       (Ctx.getTypeSizeInChars(Ty) >
2133            Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2134        Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2135     IsByRef = true;
2136   }
2137 
2138   return IsByRef;
2139 }
2140 
getOpenMPNestingLevel() const2141 unsigned Sema::getOpenMPNestingLevel() const {
2142   assert(getLangOpts().OpenMP);
2143   return DSAStack->getNestingLevel();
2144 }
2145 
isInOpenMPTargetExecutionDirective() const2146 bool Sema::isInOpenMPTargetExecutionDirective() const {
2147   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2148           !DSAStack->isClauseParsingMode()) ||
2149          DSAStack->hasDirective(
2150              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2151                 SourceLocation) -> bool {
2152                return isOpenMPTargetExecutionDirective(K);
2153              },
2154              false);
2155 }
2156 
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2157 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2158                                     unsigned StopAt) {
2159   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2160   D = getCanonicalDecl(D);
2161 
2162   auto *VD = dyn_cast<VarDecl>(D);
2163   // Do not capture constexpr variables.
2164   if (VD && VD->isConstexpr())
2165     return nullptr;
2166 
2167   // If we want to determine whether the variable should be captured from the
2168   // perspective of the current capturing scope, and we've already left all the
2169   // capturing scopes of the top directive on the stack, check from the
2170   // perspective of its parent directive (if any) instead.
2171   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2172       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2173 
2174   // If we are attempting to capture a global variable in a directive with
2175   // 'target' we return true so that this global is also mapped to the device.
2176   //
2177   if (VD && !VD->hasLocalStorage() &&
2178       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2179     if (isInOpenMPDeclareTargetContext()) {
2180       // Try to mark variable as declare target if it is used in capturing
2181       // regions.
2182       if (LangOpts.OpenMP <= 45 &&
2183           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2184         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2185       return nullptr;
2186     }
2187     if (isInOpenMPTargetExecutionDirective()) {
2188       // If the declaration is enclosed in a 'declare target' directive,
2189       // then it should not be captured.
2190       //
2191       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2192         return nullptr;
2193       CapturedRegionScopeInfo *CSI = nullptr;
2194       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2195                llvm::reverse(FunctionScopes),
2196                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2197         if (!isa<CapturingScopeInfo>(FSI))
2198           return nullptr;
2199         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2200           if (RSI->CapRegionKind == CR_OpenMP) {
2201             CSI = RSI;
2202             break;
2203           }
2204       }
2205       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2206       SmallVector<OpenMPDirectiveKind, 4> Regions;
2207       getOpenMPCaptureRegions(Regions,
2208                               DSAStack->getDirective(CSI->OpenMPLevel));
2209       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2210         return VD;
2211     }
2212   }
2213 
2214   if (CheckScopeInfo) {
2215     bool OpenMPFound = false;
2216     for (unsigned I = StopAt + 1; I > 0; --I) {
2217       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2218       if(!isa<CapturingScopeInfo>(FSI))
2219         return nullptr;
2220       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2221         if (RSI->CapRegionKind == CR_OpenMP) {
2222           OpenMPFound = true;
2223           break;
2224         }
2225     }
2226     if (!OpenMPFound)
2227       return nullptr;
2228   }
2229 
2230   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2231       (!DSAStack->isClauseParsingMode() ||
2232        DSAStack->getParentDirective() != OMPD_unknown)) {
2233     auto &&Info = DSAStack->isLoopControlVariable(D);
2234     if (Info.first ||
2235         (VD && VD->hasLocalStorage() &&
2236          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2237         (VD && DSAStack->isForceVarCapturing()))
2238       return VD ? VD : Info.second;
2239     DSAStackTy::DSAVarData DVarTop =
2240         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2241     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2242         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2243       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2244     // Threadprivate variables must not be captured.
2245     if (isOpenMPThreadPrivate(DVarTop.CKind))
2246       return nullptr;
2247     // The variable is not private or it is the variable in the directive with
2248     // default(none) clause and not used in any clause.
2249     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2250         D,
2251         [](OpenMPClauseKind C, bool AppliedToPointee) {
2252           return isOpenMPPrivate(C) && !AppliedToPointee;
2253         },
2254         [](OpenMPDirectiveKind) { return true; },
2255         DSAStack->isClauseParsingMode());
2256     // Global shared must not be captured.
2257     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2258         ((DSAStack->getDefaultDSA() != DSA_none &&
2259           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2260          DVarTop.CKind == OMPC_shared))
2261       return nullptr;
2262     if (DVarPrivate.CKind != OMPC_unknown ||
2263         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2264                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2265       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2266   }
2267   return nullptr;
2268 }
2269 
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2270 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2271                                         unsigned Level) const {
2272   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2273 }
2274 
startOpenMPLoop()2275 void Sema::startOpenMPLoop() {
2276   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2277   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2278     DSAStack->loopInit();
2279 }
2280 
startOpenMPCXXRangeFor()2281 void Sema::startOpenMPCXXRangeFor() {
2282   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2283   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2284     DSAStack->resetPossibleLoopCounter();
2285     DSAStack->loopStart();
2286   }
2287 }
2288 
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2289 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2290                                            unsigned CapLevel) const {
2291   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2292   if (DSAStack->hasExplicitDirective(
2293           [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2294           Level)) {
2295     bool IsTriviallyCopyable =
2296         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2297         !D->getType()
2298              .getNonReferenceType()
2299              .getCanonicalType()
2300              ->getAsCXXRecordDecl();
2301     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2302     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2303     getOpenMPCaptureRegions(CaptureRegions, DKind);
2304     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2305         (IsTriviallyCopyable ||
2306          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2307       if (DSAStack->hasExplicitDSA(
2308               D,
2309               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2310               Level, /*NotLastprivate=*/true))
2311         return OMPC_firstprivate;
2312       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2313       if (DVar.CKind != OMPC_shared &&
2314           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2315         DSAStack->addImplicitTaskFirstprivate(Level, D);
2316         return OMPC_firstprivate;
2317       }
2318     }
2319   }
2320   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2321     if (DSAStack->getAssociatedLoops() > 0 &&
2322         !DSAStack->isLoopStarted()) {
2323       DSAStack->resetPossibleLoopCounter(D);
2324       DSAStack->loopStart();
2325       return OMPC_private;
2326     }
2327     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2328          DSAStack->isLoopControlVariable(D).first) &&
2329         !DSAStack->hasExplicitDSA(
2330             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2331             Level) &&
2332         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2333       return OMPC_private;
2334   }
2335   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2336     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2337         DSAStack->isForceVarCapturing() &&
2338         !DSAStack->hasExplicitDSA(
2339             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2340             Level))
2341       return OMPC_private;
2342   }
2343   // User-defined allocators are private since they must be defined in the
2344   // context of target region.
2345   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2346       DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2347           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2348           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2349     return OMPC_private;
2350   return (DSAStack->hasExplicitDSA(
2351               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2352               Level) ||
2353           (DSAStack->isClauseParsingMode() &&
2354            DSAStack->getClauseParsingMode() == OMPC_private) ||
2355           // Consider taskgroup reduction descriptor variable a private
2356           // to avoid possible capture in the region.
2357           (DSAStack->hasExplicitDirective(
2358                [](OpenMPDirectiveKind K) {
2359                  return K == OMPD_taskgroup ||
2360                         ((isOpenMPParallelDirective(K) ||
2361                           isOpenMPWorksharingDirective(K)) &&
2362                          !isOpenMPSimdDirective(K));
2363                },
2364                Level) &&
2365            DSAStack->isTaskgroupReductionRef(D, Level)))
2366              ? OMPC_private
2367              : OMPC_unknown;
2368 }
2369 
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2370 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2371                                 unsigned Level) {
2372   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2373   D = getCanonicalDecl(D);
2374   OpenMPClauseKind OMPC = OMPC_unknown;
2375   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2376     const unsigned NewLevel = I - 1;
2377     if (DSAStack->hasExplicitDSA(
2378             D,
2379             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2380               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2381                 OMPC = K;
2382                 return true;
2383               }
2384               return false;
2385             },
2386             NewLevel))
2387       break;
2388     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2389             D, NewLevel,
2390             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2391                OpenMPClauseKind) { return true; })) {
2392       OMPC = OMPC_map;
2393       break;
2394     }
2395     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2396                                        NewLevel)) {
2397       OMPC = OMPC_map;
2398       if (DSAStack->mustBeFirstprivateAtLevel(
2399               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2400         OMPC = OMPC_firstprivate;
2401       break;
2402     }
2403   }
2404   if (OMPC != OMPC_unknown)
2405     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2406 }
2407 
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2408 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2409                                       unsigned CaptureLevel) const {
2410   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2411   // Return true if the current level is no longer enclosed in a target region.
2412 
2413   SmallVector<OpenMPDirectiveKind, 4> Regions;
2414   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2415   const auto *VD = dyn_cast<VarDecl>(D);
2416   return VD && !VD->hasLocalStorage() &&
2417          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2418                                         Level) &&
2419          Regions[CaptureLevel] != OMPD_task;
2420 }
2421 
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2422 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2423                                       unsigned CaptureLevel) const {
2424   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2425   // Return true if the current level is no longer enclosed in a target region.
2426 
2427   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2428     if (!VD->hasLocalStorage()) {
2429       if (isInOpenMPTargetExecutionDirective())
2430         return true;
2431       DSAStackTy::DSAVarData TopDVar =
2432           DSAStack->getTopDSA(D, /*FromParent=*/false);
2433       unsigned NumLevels =
2434           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2435       if (Level == 0)
2436         return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2437       do {
2438         --Level;
2439         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2440         if (DVar.CKind != OMPC_shared)
2441           return true;
2442       } while (Level > 0);
2443     }
2444   }
2445   return true;
2446 }
2447 
DestroyDataSharingAttributesStack()2448 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2449 
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2450 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2451                                           OMPTraitInfo &TI) {
2452   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2453 }
2454 
ActOnOpenMPEndDeclareVariant()2455 void Sema::ActOnOpenMPEndDeclareVariant() {
2456   assert(isInOpenMPDeclareVariantScope() &&
2457          "Not in OpenMP declare variant scope!");
2458 
2459   OMPDeclareVariantScopes.pop_back();
2460 }
2461 
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2462 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2463                                          const FunctionDecl *Callee,
2464                                          SourceLocation Loc) {
2465   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2466   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2467       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2468   // Ignore host functions during device analyzis.
2469   if (LangOpts.OpenMPIsDevice && DevTy &&
2470       *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2471     return;
2472   // Ignore nohost functions during host analyzis.
2473   if (!LangOpts.OpenMPIsDevice && DevTy &&
2474       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2475     return;
2476   const FunctionDecl *FD = Callee->getMostRecentDecl();
2477   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2478   if (LangOpts.OpenMPIsDevice && DevTy &&
2479       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2480     // Diagnose host function called during device codegen.
2481     StringRef HostDevTy =
2482         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2483     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2484     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2485          diag::note_omp_marked_device_type_here)
2486         << HostDevTy;
2487     return;
2488   }
2489       if (!LangOpts.OpenMPIsDevice && DevTy &&
2490           *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2491         // Diagnose nohost function called during host codegen.
2492         StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2493             OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2494         Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2495         Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2496              diag::note_omp_marked_device_type_here)
2497             << NoHostDevTy;
2498       }
2499 }
2500 
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2501 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2502                                const DeclarationNameInfo &DirName,
2503                                Scope *CurScope, SourceLocation Loc) {
2504   DSAStack->push(DKind, DirName, CurScope, Loc);
2505   PushExpressionEvaluationContext(
2506       ExpressionEvaluationContext::PotentiallyEvaluated);
2507 }
2508 
StartOpenMPClause(OpenMPClauseKind K)2509 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2510   DSAStack->setClauseParsingMode(K);
2511 }
2512 
EndOpenMPClause()2513 void Sema::EndOpenMPClause() {
2514   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2515 }
2516 
2517 static std::pair<ValueDecl *, bool>
2518 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2519                SourceRange &ERange, bool AllowArraySection = false);
2520 
2521 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2522 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2523                                   ArrayRef<OMPClause *> Clauses) {
2524   bool InscanFound = false;
2525   SourceLocation InscanLoc;
2526   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2527   // A reduction clause without the inscan reduction-modifier may not appear on
2528   // a construct on which a reduction clause with the inscan reduction-modifier
2529   // appears.
2530   for (OMPClause *C : Clauses) {
2531     if (C->getClauseKind() != OMPC_reduction)
2532       continue;
2533     auto *RC = cast<OMPReductionClause>(C);
2534     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2535       InscanFound = true;
2536       InscanLoc = RC->getModifierLoc();
2537       continue;
2538     }
2539     if (RC->getModifier() == OMPC_REDUCTION_task) {
2540       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2541       // A reduction clause with the task reduction-modifier may only appear on
2542       // a parallel construct, a worksharing construct or a combined or
2543       // composite construct for which any of the aforementioned constructs is a
2544       // constituent construct and simd or loop are not constituent constructs.
2545       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2546       if (!(isOpenMPParallelDirective(CurDir) ||
2547             isOpenMPWorksharingDirective(CurDir)) ||
2548           isOpenMPSimdDirective(CurDir))
2549         S.Diag(RC->getModifierLoc(),
2550                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2551       continue;
2552     }
2553   }
2554   if (InscanFound) {
2555     for (OMPClause *C : Clauses) {
2556       if (C->getClauseKind() != OMPC_reduction)
2557         continue;
2558       auto *RC = cast<OMPReductionClause>(C);
2559       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2560         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2561                    ? RC->getBeginLoc()
2562                    : RC->getModifierLoc(),
2563                diag::err_omp_inscan_reduction_expected);
2564         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2565         continue;
2566       }
2567       for (Expr *Ref : RC->varlists()) {
2568         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2569         SourceLocation ELoc;
2570         SourceRange ERange;
2571         Expr *SimpleRefExpr = Ref;
2572         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2573                                   /*AllowArraySection=*/true);
2574         ValueDecl *D = Res.first;
2575         if (!D)
2576           continue;
2577         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2578           S.Diag(Ref->getExprLoc(),
2579                  diag::err_omp_reduction_not_inclusive_exclusive)
2580               << Ref->getSourceRange();
2581         }
2582       }
2583     }
2584   }
2585 }
2586 
2587 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2588                                  ArrayRef<OMPClause *> Clauses);
2589 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2590                                  bool WithInit);
2591 
2592 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2593                               const ValueDecl *D,
2594                               const DSAStackTy::DSAVarData &DVar,
2595                               bool IsLoopIterVar = false);
2596 
EndOpenMPDSABlock(Stmt * CurDirective)2597 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2598   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2599   //  A variable of class type (or array thereof) that appears in a lastprivate
2600   //  clause requires an accessible, unambiguous default constructor for the
2601   //  class type, unless the list item is also specified in a firstprivate
2602   //  clause.
2603   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2604     for (OMPClause *C : D->clauses()) {
2605       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2606         SmallVector<Expr *, 8> PrivateCopies;
2607         for (Expr *DE : Clause->varlists()) {
2608           if (DE->isValueDependent() || DE->isTypeDependent()) {
2609             PrivateCopies.push_back(nullptr);
2610             continue;
2611           }
2612           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2613           auto *VD = cast<VarDecl>(DRE->getDecl());
2614           QualType Type = VD->getType().getNonReferenceType();
2615           const DSAStackTy::DSAVarData DVar =
2616               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2617           if (DVar.CKind == OMPC_lastprivate) {
2618             // Generate helper private variable and initialize it with the
2619             // default value. The address of the original variable is replaced
2620             // by the address of the new private variable in CodeGen. This new
2621             // variable is not added to IdResolver, so the code in the OpenMP
2622             // region uses original variable for proper diagnostics.
2623             VarDecl *VDPrivate = buildVarDecl(
2624                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2625                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2626             ActOnUninitializedDecl(VDPrivate);
2627             if (VDPrivate->isInvalidDecl()) {
2628               PrivateCopies.push_back(nullptr);
2629               continue;
2630             }
2631             PrivateCopies.push_back(buildDeclRefExpr(
2632                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2633           } else {
2634             // The variable is also a firstprivate, so initialization sequence
2635             // for private copy is generated already.
2636             PrivateCopies.push_back(nullptr);
2637           }
2638         }
2639         Clause->setPrivateCopies(PrivateCopies);
2640         continue;
2641       }
2642       // Finalize nontemporal clause by handling private copies, if any.
2643       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2644         SmallVector<Expr *, 8> PrivateRefs;
2645         for (Expr *RefExpr : Clause->varlists()) {
2646           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2647           SourceLocation ELoc;
2648           SourceRange ERange;
2649           Expr *SimpleRefExpr = RefExpr;
2650           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2651           if (Res.second)
2652             // It will be analyzed later.
2653             PrivateRefs.push_back(RefExpr);
2654           ValueDecl *D = Res.first;
2655           if (!D)
2656             continue;
2657 
2658           const DSAStackTy::DSAVarData DVar =
2659               DSAStack->getTopDSA(D, /*FromParent=*/false);
2660           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2661                                                  : SimpleRefExpr);
2662         }
2663         Clause->setPrivateRefs(PrivateRefs);
2664         continue;
2665       }
2666       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2667         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2668           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2669           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2670           if (!DRE)
2671             continue;
2672           ValueDecl *VD = DRE->getDecl();
2673           if (!VD || !isa<VarDecl>(VD))
2674             continue;
2675           DSAStackTy::DSAVarData DVar =
2676               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2677           // OpenMP [2.12.5, target Construct]
2678           // Memory allocators that appear in a uses_allocators clause cannot
2679           // appear in other data-sharing attribute clauses or data-mapping
2680           // attribute clauses in the same construct.
2681           Expr *MapExpr = nullptr;
2682           if (DVar.RefExpr ||
2683               DSAStack->checkMappableExprComponentListsForDecl(
2684                   VD, /*CurrentRegionOnly=*/true,
2685                   [VD, &MapExpr](
2686                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2687                           MapExprComponents,
2688                       OpenMPClauseKind C) {
2689                     auto MI = MapExprComponents.rbegin();
2690                     auto ME = MapExprComponents.rend();
2691                     if (MI != ME &&
2692                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2693                             VD->getCanonicalDecl()) {
2694                       MapExpr = MI->getAssociatedExpression();
2695                       return true;
2696                     }
2697                     return false;
2698                   })) {
2699             Diag(D.Allocator->getExprLoc(),
2700                  diag::err_omp_allocator_used_in_clauses)
2701                 << D.Allocator->getSourceRange();
2702             if (DVar.RefExpr)
2703               reportOriginalDsa(*this, DSAStack, VD, DVar);
2704             else
2705               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2706                   << MapExpr->getSourceRange();
2707           }
2708         }
2709         continue;
2710       }
2711     }
2712     // Check allocate clauses.
2713     if (!CurContext->isDependentContext())
2714       checkAllocateClauses(*this, DSAStack, D->clauses());
2715     checkReductionClauses(*this, DSAStack, D->clauses());
2716   }
2717 
2718   DSAStack->pop();
2719   DiscardCleanupsInEvaluationContext();
2720   PopExpressionEvaluationContext();
2721 }
2722 
2723 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2724                                      Expr *NumIterations, Sema &SemaRef,
2725                                      Scope *S, DSAStackTy *Stack);
2726 
2727 namespace {
2728 
2729 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2730 private:
2731   Sema &SemaRef;
2732 
2733 public:
VarDeclFilterCCC(Sema & S)2734   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2735   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2736     NamedDecl *ND = Candidate.getCorrectionDecl();
2737     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2738       return VD->hasGlobalStorage() &&
2739              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2740                                    SemaRef.getCurScope());
2741     }
2742     return false;
2743   }
2744 
clone()2745   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2746     return std::make_unique<VarDeclFilterCCC>(*this);
2747   }
2748 
2749 };
2750 
2751 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2752 private:
2753   Sema &SemaRef;
2754 
2755 public:
VarOrFuncDeclFilterCCC(Sema & S)2756   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2757   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2758     NamedDecl *ND = Candidate.getCorrectionDecl();
2759     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2760                isa<FunctionDecl>(ND))) {
2761       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2762                                    SemaRef.getCurScope());
2763     }
2764     return false;
2765   }
2766 
clone()2767   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2768     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2769   }
2770 };
2771 
2772 } // namespace
2773 
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2774 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2775                                          CXXScopeSpec &ScopeSpec,
2776                                          const DeclarationNameInfo &Id,
2777                                          OpenMPDirectiveKind Kind) {
2778   LookupResult Lookup(*this, Id, LookupOrdinaryName);
2779   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2780 
2781   if (Lookup.isAmbiguous())
2782     return ExprError();
2783 
2784   VarDecl *VD;
2785   if (!Lookup.isSingleResult()) {
2786     VarDeclFilterCCC CCC(*this);
2787     if (TypoCorrection Corrected =
2788             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2789                         CTK_ErrorRecovery)) {
2790       diagnoseTypo(Corrected,
2791                    PDiag(Lookup.empty()
2792                              ? diag::err_undeclared_var_use_suggest
2793                              : diag::err_omp_expected_var_arg_suggest)
2794                        << Id.getName());
2795       VD = Corrected.getCorrectionDeclAs<VarDecl>();
2796     } else {
2797       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2798                                        : diag::err_omp_expected_var_arg)
2799           << Id.getName();
2800       return ExprError();
2801     }
2802   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2803     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2804     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2805     return ExprError();
2806   }
2807   Lookup.suppressDiagnostics();
2808 
2809   // OpenMP [2.9.2, Syntax, C/C++]
2810   //   Variables must be file-scope, namespace-scope, or static block-scope.
2811   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2812     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2813         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2814     bool IsDecl =
2815         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2816     Diag(VD->getLocation(),
2817          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2818         << VD;
2819     return ExprError();
2820   }
2821 
2822   VarDecl *CanonicalVD = VD->getCanonicalDecl();
2823   NamedDecl *ND = CanonicalVD;
2824   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2825   //   A threadprivate directive for file-scope variables must appear outside
2826   //   any definition or declaration.
2827   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2828       !getCurLexicalContext()->isTranslationUnit()) {
2829     Diag(Id.getLoc(), diag::err_omp_var_scope)
2830         << getOpenMPDirectiveName(Kind) << VD;
2831     bool IsDecl =
2832         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2833     Diag(VD->getLocation(),
2834          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2835         << VD;
2836     return ExprError();
2837   }
2838   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2839   //   A threadprivate directive for static class member variables must appear
2840   //   in the class definition, in the same scope in which the member
2841   //   variables are declared.
2842   if (CanonicalVD->isStaticDataMember() &&
2843       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2844     Diag(Id.getLoc(), diag::err_omp_var_scope)
2845         << getOpenMPDirectiveName(Kind) << VD;
2846     bool IsDecl =
2847         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2848     Diag(VD->getLocation(),
2849          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2850         << VD;
2851     return ExprError();
2852   }
2853   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2854   //   A threadprivate directive for namespace-scope variables must appear
2855   //   outside any definition or declaration other than the namespace
2856   //   definition itself.
2857   if (CanonicalVD->getDeclContext()->isNamespace() &&
2858       (!getCurLexicalContext()->isFileContext() ||
2859        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2860     Diag(Id.getLoc(), diag::err_omp_var_scope)
2861         << getOpenMPDirectiveName(Kind) << VD;
2862     bool IsDecl =
2863         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2864     Diag(VD->getLocation(),
2865          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2866         << VD;
2867     return ExprError();
2868   }
2869   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2870   //   A threadprivate directive for static block-scope variables must appear
2871   //   in the scope of the variable and not in a nested scope.
2872   if (CanonicalVD->isLocalVarDecl() && CurScope &&
2873       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2874     Diag(Id.getLoc(), diag::err_omp_var_scope)
2875         << getOpenMPDirectiveName(Kind) << VD;
2876     bool IsDecl =
2877         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2878     Diag(VD->getLocation(),
2879          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2880         << VD;
2881     return ExprError();
2882   }
2883 
2884   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2885   //   A threadprivate directive must lexically precede all references to any
2886   //   of the variables in its list.
2887   if (Kind == OMPD_threadprivate && VD->isUsed() &&
2888       !DSAStack->isThreadPrivate(VD)) {
2889     Diag(Id.getLoc(), diag::err_omp_var_used)
2890         << getOpenMPDirectiveName(Kind) << VD;
2891     return ExprError();
2892   }
2893 
2894   QualType ExprType = VD->getType().getNonReferenceType();
2895   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2896                              SourceLocation(), VD,
2897                              /*RefersToEnclosingVariableOrCapture=*/false,
2898                              Id.getLoc(), ExprType, VK_LValue);
2899 }
2900 
2901 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)2902 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2903                                         ArrayRef<Expr *> VarList) {
2904   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2905     CurContext->addDecl(D);
2906     return DeclGroupPtrTy::make(DeclGroupRef(D));
2907   }
2908   return nullptr;
2909 }
2910 
2911 namespace {
2912 class LocalVarRefChecker final
2913     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2914   Sema &SemaRef;
2915 
2916 public:
VisitDeclRefExpr(const DeclRefExpr * E)2917   bool VisitDeclRefExpr(const DeclRefExpr *E) {
2918     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2919       if (VD->hasLocalStorage()) {
2920         SemaRef.Diag(E->getBeginLoc(),
2921                      diag::err_omp_local_var_in_threadprivate_init)
2922             << E->getSourceRange();
2923         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2924             << VD << VD->getSourceRange();
2925         return true;
2926       }
2927     }
2928     return false;
2929   }
VisitStmt(const Stmt * S)2930   bool VisitStmt(const Stmt *S) {
2931     for (const Stmt *Child : S->children()) {
2932       if (Child && Visit(Child))
2933         return true;
2934     }
2935     return false;
2936   }
LocalVarRefChecker(Sema & SemaRef)2937   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2938 };
2939 } // namespace
2940 
2941 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2942 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2943   SmallVector<Expr *, 8> Vars;
2944   for (Expr *RefExpr : VarList) {
2945     auto *DE = cast<DeclRefExpr>(RefExpr);
2946     auto *VD = cast<VarDecl>(DE->getDecl());
2947     SourceLocation ILoc = DE->getExprLoc();
2948 
2949     // Mark variable as used.
2950     VD->setReferenced();
2951     VD->markUsed(Context);
2952 
2953     QualType QType = VD->getType();
2954     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2955       // It will be analyzed later.
2956       Vars.push_back(DE);
2957       continue;
2958     }
2959 
2960     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2961     //   A threadprivate variable must not have an incomplete type.
2962     if (RequireCompleteType(ILoc, VD->getType(),
2963                             diag::err_omp_threadprivate_incomplete_type)) {
2964       continue;
2965     }
2966 
2967     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2968     //   A threadprivate variable must not have a reference type.
2969     if (VD->getType()->isReferenceType()) {
2970       Diag(ILoc, diag::err_omp_ref_type_arg)
2971           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2972       bool IsDecl =
2973           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2974       Diag(VD->getLocation(),
2975            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2976           << VD;
2977       continue;
2978     }
2979 
2980     // Check if this is a TLS variable. If TLS is not being supported, produce
2981     // the corresponding diagnostic.
2982     if ((VD->getTLSKind() != VarDecl::TLS_None &&
2983          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2984            getLangOpts().OpenMPUseTLS &&
2985            getASTContext().getTargetInfo().isTLSSupported())) ||
2986         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2987          !VD->isLocalVarDecl())) {
2988       Diag(ILoc, diag::err_omp_var_thread_local)
2989           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2990       bool IsDecl =
2991           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2992       Diag(VD->getLocation(),
2993            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2994           << VD;
2995       continue;
2996     }
2997 
2998     // Check if initial value of threadprivate variable reference variable with
2999     // local storage (it is not supported by runtime).
3000     if (const Expr *Init = VD->getAnyInitializer()) {
3001       LocalVarRefChecker Checker(*this);
3002       if (Checker.Visit(Init))
3003         continue;
3004     }
3005 
3006     Vars.push_back(RefExpr);
3007     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3008     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3009         Context, SourceRange(Loc, Loc)));
3010     if (ASTMutationListener *ML = Context.getASTMutationListener())
3011       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3012   }
3013   OMPThreadPrivateDecl *D = nullptr;
3014   if (!Vars.empty()) {
3015     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3016                                      Vars);
3017     D->setAccess(AS_public);
3018   }
3019   return D;
3020 }
3021 
3022 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3023 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3024   if (!Allocator)
3025     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3026   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3027       Allocator->isInstantiationDependent() ||
3028       Allocator->containsUnexpandedParameterPack())
3029     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3030   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3031   const Expr *AE = Allocator->IgnoreParenImpCasts();
3032   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3033     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3034     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3035     llvm::FoldingSetNodeID AEId, DAEId;
3036     AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3037     DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3038     if (AEId == DAEId) {
3039       AllocatorKindRes = AllocatorKind;
3040       break;
3041     }
3042   }
3043   return AllocatorKindRes;
3044 }
3045 
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3046 static bool checkPreviousOMPAllocateAttribute(
3047     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3048     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3049   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3050     return false;
3051   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3052   Expr *PrevAllocator = A->getAllocator();
3053   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3054       getAllocatorKind(S, Stack, PrevAllocator);
3055   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3056   if (AllocatorsMatch &&
3057       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3058       Allocator && PrevAllocator) {
3059     const Expr *AE = Allocator->IgnoreParenImpCasts();
3060     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3061     llvm::FoldingSetNodeID AEId, PAEId;
3062     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3063     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3064     AllocatorsMatch = AEId == PAEId;
3065   }
3066   if (!AllocatorsMatch) {
3067     SmallString<256> AllocatorBuffer;
3068     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3069     if (Allocator)
3070       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3071     SmallString<256> PrevAllocatorBuffer;
3072     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3073     if (PrevAllocator)
3074       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3075                                  S.getPrintingPolicy());
3076 
3077     SourceLocation AllocatorLoc =
3078         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3079     SourceRange AllocatorRange =
3080         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3081     SourceLocation PrevAllocatorLoc =
3082         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3083     SourceRange PrevAllocatorRange =
3084         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3085     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3086         << (Allocator ? 1 : 0) << AllocatorStream.str()
3087         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3088         << AllocatorRange;
3089     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3090         << PrevAllocatorRange;
3091     return true;
3092   }
3093   return false;
3094 }
3095 
3096 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,SourceRange SR)3097 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3098                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3099                           Expr *Allocator, SourceRange SR) {
3100   if (VD->hasAttr<OMPAllocateDeclAttr>())
3101     return;
3102   if (Allocator &&
3103       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3104        Allocator->isInstantiationDependent() ||
3105        Allocator->containsUnexpandedParameterPack()))
3106     return;
3107   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3108                                                 Allocator, SR);
3109   VD->addAttr(A);
3110   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3111     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3112 }
3113 
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3114 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3115     SourceLocation Loc, ArrayRef<Expr *> VarList,
3116     ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3117   assert(Clauses.size() <= 1 && "Expected at most one clause.");
3118   Expr *Allocator = nullptr;
3119   if (Clauses.empty()) {
3120     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3121     // allocate directives that appear in a target region must specify an
3122     // allocator clause unless a requires directive with the dynamic_allocators
3123     // clause is present in the same compilation unit.
3124     if (LangOpts.OpenMPIsDevice &&
3125         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3126       targetDiag(Loc, diag::err_expected_allocator_clause);
3127   } else {
3128     Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3129   }
3130   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3131       getAllocatorKind(*this, DSAStack, Allocator);
3132   SmallVector<Expr *, 8> Vars;
3133   for (Expr *RefExpr : VarList) {
3134     auto *DE = cast<DeclRefExpr>(RefExpr);
3135     auto *VD = cast<VarDecl>(DE->getDecl());
3136 
3137     // Check if this is a TLS variable or global register.
3138     if (VD->getTLSKind() != VarDecl::TLS_None ||
3139         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3140         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3141          !VD->isLocalVarDecl()))
3142       continue;
3143 
3144     // If the used several times in the allocate directive, the same allocator
3145     // must be used.
3146     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3147                                           AllocatorKind, Allocator))
3148       continue;
3149 
3150     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3151     // If a list item has a static storage type, the allocator expression in the
3152     // allocator clause must be a constant expression that evaluates to one of
3153     // the predefined memory allocator values.
3154     if (Allocator && VD->hasGlobalStorage()) {
3155       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3156         Diag(Allocator->getExprLoc(),
3157              diag::err_omp_expected_predefined_allocator)
3158             << Allocator->getSourceRange();
3159         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3160                       VarDecl::DeclarationOnly;
3161         Diag(VD->getLocation(),
3162              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3163             << VD;
3164         continue;
3165       }
3166     }
3167 
3168     Vars.push_back(RefExpr);
3169     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3170                               DE->getSourceRange());
3171   }
3172   if (Vars.empty())
3173     return nullptr;
3174   if (!Owner)
3175     Owner = getCurLexicalContext();
3176   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3177   D->setAccess(AS_public);
3178   Owner->addDecl(D);
3179   return DeclGroupPtrTy::make(DeclGroupRef(D));
3180 }
3181 
3182 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3183 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3184                                    ArrayRef<OMPClause *> ClauseList) {
3185   OMPRequiresDecl *D = nullptr;
3186   if (!CurContext->isFileContext()) {
3187     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3188   } else {
3189     D = CheckOMPRequiresDecl(Loc, ClauseList);
3190     if (D) {
3191       CurContext->addDecl(D);
3192       DSAStack->addRequiresDecl(D);
3193     }
3194   }
3195   return DeclGroupPtrTy::make(DeclGroupRef(D));
3196 }
3197 
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3198 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3199                                             ArrayRef<OMPClause *> ClauseList) {
3200   /// For target specific clauses, the requires directive cannot be
3201   /// specified after the handling of any of the target regions in the
3202   /// current compilation unit.
3203   ArrayRef<SourceLocation> TargetLocations =
3204       DSAStack->getEncounteredTargetLocs();
3205   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3206   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3207     for (const OMPClause *CNew : ClauseList) {
3208       // Check if any of the requires clauses affect target regions.
3209       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3210           isa<OMPUnifiedAddressClause>(CNew) ||
3211           isa<OMPReverseOffloadClause>(CNew) ||
3212           isa<OMPDynamicAllocatorsClause>(CNew)) {
3213         Diag(Loc, diag::err_omp_directive_before_requires)
3214             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3215         for (SourceLocation TargetLoc : TargetLocations) {
3216           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3217               << "target";
3218         }
3219       } else if (!AtomicLoc.isInvalid() &&
3220                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3221         Diag(Loc, diag::err_omp_directive_before_requires)
3222             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3223         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3224             << "atomic";
3225       }
3226     }
3227   }
3228 
3229   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3230     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3231                                    ClauseList);
3232   return nullptr;
3233 }
3234 
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3235 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3236                               const ValueDecl *D,
3237                               const DSAStackTy::DSAVarData &DVar,
3238                               bool IsLoopIterVar) {
3239   if (DVar.RefExpr) {
3240     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3241         << getOpenMPClauseName(DVar.CKind);
3242     return;
3243   }
3244   enum {
3245     PDSA_StaticMemberShared,
3246     PDSA_StaticLocalVarShared,
3247     PDSA_LoopIterVarPrivate,
3248     PDSA_LoopIterVarLinear,
3249     PDSA_LoopIterVarLastprivate,
3250     PDSA_ConstVarShared,
3251     PDSA_GlobalVarShared,
3252     PDSA_TaskVarFirstprivate,
3253     PDSA_LocalVarPrivate,
3254     PDSA_Implicit
3255   } Reason = PDSA_Implicit;
3256   bool ReportHint = false;
3257   auto ReportLoc = D->getLocation();
3258   auto *VD = dyn_cast<VarDecl>(D);
3259   if (IsLoopIterVar) {
3260     if (DVar.CKind == OMPC_private)
3261       Reason = PDSA_LoopIterVarPrivate;
3262     else if (DVar.CKind == OMPC_lastprivate)
3263       Reason = PDSA_LoopIterVarLastprivate;
3264     else
3265       Reason = PDSA_LoopIterVarLinear;
3266   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3267              DVar.CKind == OMPC_firstprivate) {
3268     Reason = PDSA_TaskVarFirstprivate;
3269     ReportLoc = DVar.ImplicitDSALoc;
3270   } else if (VD && VD->isStaticLocal())
3271     Reason = PDSA_StaticLocalVarShared;
3272   else if (VD && VD->isStaticDataMember())
3273     Reason = PDSA_StaticMemberShared;
3274   else if (VD && VD->isFileVarDecl())
3275     Reason = PDSA_GlobalVarShared;
3276   else if (D->getType().isConstant(SemaRef.getASTContext()))
3277     Reason = PDSA_ConstVarShared;
3278   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3279     ReportHint = true;
3280     Reason = PDSA_LocalVarPrivate;
3281   }
3282   if (Reason != PDSA_Implicit) {
3283     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3284         << Reason << ReportHint
3285         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3286   } else if (DVar.ImplicitDSALoc.isValid()) {
3287     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3288         << getOpenMPClauseName(DVar.CKind);
3289   }
3290 }
3291 
3292 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3293 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3294                              bool IsAggregateOrDeclareTarget) {
3295   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3296   switch (M) {
3297   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3298     Kind = OMPC_MAP_alloc;
3299     break;
3300   case OMPC_DEFAULTMAP_MODIFIER_to:
3301     Kind = OMPC_MAP_to;
3302     break;
3303   case OMPC_DEFAULTMAP_MODIFIER_from:
3304     Kind = OMPC_MAP_from;
3305     break;
3306   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3307     Kind = OMPC_MAP_tofrom;
3308     break;
3309   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3310   case OMPC_DEFAULTMAP_MODIFIER_last:
3311     llvm_unreachable("Unexpected defaultmap implicit behavior");
3312   case OMPC_DEFAULTMAP_MODIFIER_none:
3313   case OMPC_DEFAULTMAP_MODIFIER_default:
3314   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3315     // IsAggregateOrDeclareTarget could be true if:
3316     // 1. the implicit behavior for aggregate is tofrom
3317     // 2. it's a declare target link
3318     if (IsAggregateOrDeclareTarget) {
3319       Kind = OMPC_MAP_tofrom;
3320       break;
3321     }
3322     llvm_unreachable("Unexpected defaultmap implicit behavior");
3323   }
3324   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3325   return Kind;
3326 }
3327 
3328 namespace {
3329 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3330   DSAStackTy *Stack;
3331   Sema &SemaRef;
3332   bool ErrorFound = false;
3333   bool TryCaptureCXXThisMembers = false;
3334   CapturedStmt *CS = nullptr;
3335   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3336   llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3337   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3338   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3339 
VisitSubCaptures(OMPExecutableDirective * S)3340   void VisitSubCaptures(OMPExecutableDirective *S) {
3341     // Check implicitly captured variables.
3342     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3343       return;
3344     if (S->getDirectiveKind() == OMPD_atomic ||
3345         S->getDirectiveKind() == OMPD_critical ||
3346         S->getDirectiveKind() == OMPD_section ||
3347         S->getDirectiveKind() == OMPD_master) {
3348       Visit(S->getAssociatedStmt());
3349       return;
3350     }
3351     visitSubCaptures(S->getInnermostCapturedStmt());
3352     // Try to capture inner this->member references to generate correct mappings
3353     // and diagnostics.
3354     if (TryCaptureCXXThisMembers ||
3355         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3356          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3357                       [](const CapturedStmt::Capture &C) {
3358                         return C.capturesThis();
3359                       }))) {
3360       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3361       TryCaptureCXXThisMembers = true;
3362       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3363       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3364     }
3365     // In tasks firstprivates are not captured anymore, need to analyze them
3366     // explicitly.
3367     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3368         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3369       for (OMPClause *C : S->clauses())
3370         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3371           for (Expr *Ref : FC->varlists())
3372             Visit(Ref);
3373         }
3374     }
3375   }
3376 
3377 public:
VisitDeclRefExpr(DeclRefExpr * E)3378   void VisitDeclRefExpr(DeclRefExpr *E) {
3379     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3380         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3381         E->isInstantiationDependent())
3382       return;
3383     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3384       // Check the datasharing rules for the expressions in the clauses.
3385       if (!CS) {
3386         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3387           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3388             Visit(CED->getInit());
3389             return;
3390           }
3391       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3392         // Do not analyze internal variables and do not enclose them into
3393         // implicit clauses.
3394         return;
3395       VD = VD->getCanonicalDecl();
3396       // Skip internally declared variables.
3397       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3398           !Stack->isImplicitTaskFirstprivate(VD))
3399         return;
3400       // Skip allocators in uses_allocators clauses.
3401       if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3402         return;
3403 
3404       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3405       // Check if the variable has explicit DSA set and stop analysis if it so.
3406       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3407         return;
3408 
3409       // Skip internally declared static variables.
3410       llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3411           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3412       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3413           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3414            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3415           !Stack->isImplicitTaskFirstprivate(VD))
3416         return;
3417 
3418       SourceLocation ELoc = E->getExprLoc();
3419       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3420       // The default(none) clause requires that each variable that is referenced
3421       // in the construct, and does not have a predetermined data-sharing
3422       // attribute, must have its data-sharing attribute explicitly determined
3423       // by being listed in a data-sharing attribute clause.
3424       if (DVar.CKind == OMPC_unknown &&
3425           (Stack->getDefaultDSA() == DSA_none ||
3426            Stack->getDefaultDSA() == DSA_firstprivate) &&
3427           isImplicitOrExplicitTaskingRegion(DKind) &&
3428           VarsWithInheritedDSA.count(VD) == 0) {
3429         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3430         if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3431           DSAStackTy::DSAVarData DVar =
3432               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3433           InheritedDSA = DVar.CKind == OMPC_unknown;
3434         }
3435         if (InheritedDSA)
3436           VarsWithInheritedDSA[VD] = E;
3437         return;
3438       }
3439 
3440       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3441       // If implicit-behavior is none, each variable referenced in the
3442       // construct that does not have a predetermined data-sharing attribute
3443       // and does not appear in a to or link clause on a declare target
3444       // directive must be listed in a data-mapping attribute clause, a
3445       // data-haring attribute clause (including a data-sharing attribute
3446       // clause on a combined construct where target. is one of the
3447       // constituent constructs), or an is_device_ptr clause.
3448       OpenMPDefaultmapClauseKind ClauseKind =
3449           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3450       if (SemaRef.getLangOpts().OpenMP >= 50) {
3451         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3452                               OMPC_DEFAULTMAP_MODIFIER_none;
3453         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3454             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3455           // Only check for data-mapping attribute and is_device_ptr here
3456           // since we have already make sure that the declaration does not
3457           // have a data-sharing attribute above
3458           if (!Stack->checkMappableExprComponentListsForDecl(
3459                   VD, /*CurrentRegionOnly=*/true,
3460                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3461                            MapExprComponents,
3462                        OpenMPClauseKind) {
3463                     auto MI = MapExprComponents.rbegin();
3464                     auto ME = MapExprComponents.rend();
3465                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3466                   })) {
3467             VarsWithInheritedDSA[VD] = E;
3468             return;
3469           }
3470         }
3471       }
3472 
3473       if (isOpenMPTargetExecutionDirective(DKind) &&
3474           !Stack->isLoopControlVariable(VD).first) {
3475         if (!Stack->checkMappableExprComponentListsForDecl(
3476                 VD, /*CurrentRegionOnly=*/true,
3477                 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3478                        StackComponents,
3479                    OpenMPClauseKind) {
3480                   // Variable is used if it has been marked as an array, array
3481                   // section, array shaping or the variable iself.
3482                   return StackComponents.size() == 1 ||
3483                          std::all_of(
3484                              std::next(StackComponents.rbegin()),
3485                              StackComponents.rend(),
3486                              [](const OMPClauseMappableExprCommon::
3487                                     MappableComponent &MC) {
3488                                return MC.getAssociatedDeclaration() ==
3489                                           nullptr &&
3490                                       (isa<OMPArraySectionExpr>(
3491                                            MC.getAssociatedExpression()) ||
3492                                        isa<OMPArrayShapingExpr>(
3493                                            MC.getAssociatedExpression()) ||
3494                                        isa<ArraySubscriptExpr>(
3495                                            MC.getAssociatedExpression()));
3496                              });
3497                 })) {
3498           bool IsFirstprivate = false;
3499           // By default lambdas are captured as firstprivates.
3500           if (const auto *RD =
3501                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3502             IsFirstprivate = RD->isLambda();
3503           IsFirstprivate =
3504               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3505           if (IsFirstprivate) {
3506             ImplicitFirstprivate.emplace_back(E);
3507           } else {
3508             OpenMPDefaultmapClauseModifier M =
3509                 Stack->getDefaultmapModifier(ClauseKind);
3510             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3511                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3512             ImplicitMap[Kind].emplace_back(E);
3513           }
3514           return;
3515         }
3516       }
3517 
3518       // OpenMP [2.9.3.6, Restrictions, p.2]
3519       //  A list item that appears in a reduction clause of the innermost
3520       //  enclosing worksharing or parallel construct may not be accessed in an
3521       //  explicit task.
3522       DVar = Stack->hasInnermostDSA(
3523           VD,
3524           [](OpenMPClauseKind C, bool AppliedToPointee) {
3525             return C == OMPC_reduction && !AppliedToPointee;
3526           },
3527           [](OpenMPDirectiveKind K) {
3528             return isOpenMPParallelDirective(K) ||
3529                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3530           },
3531           /*FromParent=*/true);
3532       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3533         ErrorFound = true;
3534         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3535         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3536         return;
3537       }
3538 
3539       // Define implicit data-sharing attributes for task.
3540       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3541       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3542            (Stack->getDefaultDSA() == DSA_firstprivate &&
3543             DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3544           !Stack->isLoopControlVariable(VD).first) {
3545         ImplicitFirstprivate.push_back(E);
3546         return;
3547       }
3548 
3549       // Store implicitly used globals with declare target link for parent
3550       // target.
3551       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3552           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3553         Stack->addToParentTargetRegionLinkGlobals(E);
3554         return;
3555       }
3556     }
3557   }
VisitMemberExpr(MemberExpr * E)3558   void VisitMemberExpr(MemberExpr *E) {
3559     if (E->isTypeDependent() || E->isValueDependent() ||
3560         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3561       return;
3562     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3563     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3564     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3565       if (!FD)
3566         return;
3567       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3568       // Check if the variable has explicit DSA set and stop analysis if it
3569       // so.
3570       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3571         return;
3572 
3573       if (isOpenMPTargetExecutionDirective(DKind) &&
3574           !Stack->isLoopControlVariable(FD).first &&
3575           !Stack->checkMappableExprComponentListsForDecl(
3576               FD, /*CurrentRegionOnly=*/true,
3577               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3578                      StackComponents,
3579                  OpenMPClauseKind) {
3580                 return isa<CXXThisExpr>(
3581                     cast<MemberExpr>(
3582                         StackComponents.back().getAssociatedExpression())
3583                         ->getBase()
3584                         ->IgnoreParens());
3585               })) {
3586         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3587         //  A bit-field cannot appear in a map clause.
3588         //
3589         if (FD->isBitField())
3590           return;
3591 
3592         // Check to see if the member expression is referencing a class that
3593         // has already been explicitly mapped
3594         if (Stack->isClassPreviouslyMapped(TE->getType()))
3595           return;
3596 
3597         OpenMPDefaultmapClauseModifier Modifier =
3598             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3599         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3600             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3601         ImplicitMap[Kind].emplace_back(E);
3602         return;
3603       }
3604 
3605       SourceLocation ELoc = E->getExprLoc();
3606       // OpenMP [2.9.3.6, Restrictions, p.2]
3607       //  A list item that appears in a reduction clause of the innermost
3608       //  enclosing worksharing or parallel construct may not be accessed in
3609       //  an  explicit task.
3610       DVar = Stack->hasInnermostDSA(
3611           FD,
3612           [](OpenMPClauseKind C, bool AppliedToPointee) {
3613             return C == OMPC_reduction && !AppliedToPointee;
3614           },
3615           [](OpenMPDirectiveKind K) {
3616             return isOpenMPParallelDirective(K) ||
3617                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3618           },
3619           /*FromParent=*/true);
3620       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3621         ErrorFound = true;
3622         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3623         reportOriginalDsa(SemaRef, Stack, FD, DVar);
3624         return;
3625       }
3626 
3627       // Define implicit data-sharing attributes for task.
3628       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3629       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3630           !Stack->isLoopControlVariable(FD).first) {
3631         // Check if there is a captured expression for the current field in the
3632         // region. Do not mark it as firstprivate unless there is no captured
3633         // expression.
3634         // TODO: try to make it firstprivate.
3635         if (DVar.CKind != OMPC_unknown)
3636           ImplicitFirstprivate.push_back(E);
3637       }
3638       return;
3639     }
3640     if (isOpenMPTargetExecutionDirective(DKind)) {
3641       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3642       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3643                                         Stack->getCurrentDirective(),
3644                                         /*NoDiagnose=*/true))
3645         return;
3646       const auto *VD = cast<ValueDecl>(
3647           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3648       if (!Stack->checkMappableExprComponentListsForDecl(
3649               VD, /*CurrentRegionOnly=*/true,
3650               [&CurComponents](
3651                   OMPClauseMappableExprCommon::MappableExprComponentListRef
3652                       StackComponents,
3653                   OpenMPClauseKind) {
3654                 auto CCI = CurComponents.rbegin();
3655                 auto CCE = CurComponents.rend();
3656                 for (const auto &SC : llvm::reverse(StackComponents)) {
3657                   // Do both expressions have the same kind?
3658                   if (CCI->getAssociatedExpression()->getStmtClass() !=
3659                       SC.getAssociatedExpression()->getStmtClass())
3660                     if (!((isa<OMPArraySectionExpr>(
3661                                SC.getAssociatedExpression()) ||
3662                            isa<OMPArrayShapingExpr>(
3663                                SC.getAssociatedExpression())) &&
3664                           isa<ArraySubscriptExpr>(
3665                               CCI->getAssociatedExpression())))
3666                       return false;
3667 
3668                   const Decl *CCD = CCI->getAssociatedDeclaration();
3669                   const Decl *SCD = SC.getAssociatedDeclaration();
3670                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3671                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3672                   if (SCD != CCD)
3673                     return false;
3674                   std::advance(CCI, 1);
3675                   if (CCI == CCE)
3676                     break;
3677                 }
3678                 return true;
3679               })) {
3680         Visit(E->getBase());
3681       }
3682     } else if (!TryCaptureCXXThisMembers) {
3683       Visit(E->getBase());
3684     }
3685   }
VisitOMPExecutableDirective(OMPExecutableDirective * S)3686   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3687     for (OMPClause *C : S->clauses()) {
3688       // Skip analysis of arguments of implicitly defined firstprivate clause
3689       // for task|target directives.
3690       // Skip analysis of arguments of implicitly defined map clause for target
3691       // directives.
3692       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3693                  C->isImplicit() &&
3694                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3695         for (Stmt *CC : C->children()) {
3696           if (CC)
3697             Visit(CC);
3698         }
3699       }
3700     }
3701     // Check implicitly captured variables.
3702     VisitSubCaptures(S);
3703   }
VisitStmt(Stmt * S)3704   void VisitStmt(Stmt *S) {
3705     for (Stmt *C : S->children()) {
3706       if (C) {
3707         // Check implicitly captured variables in the task-based directives to
3708         // check if they must be firstprivatized.
3709         Visit(C);
3710       }
3711     }
3712   }
3713 
visitSubCaptures(CapturedStmt * S)3714   void visitSubCaptures(CapturedStmt *S) {
3715     for (const CapturedStmt::Capture &Cap : S->captures()) {
3716       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3717         continue;
3718       VarDecl *VD = Cap.getCapturedVar();
3719       // Do not try to map the variable if it or its sub-component was mapped
3720       // already.
3721       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3722           Stack->checkMappableExprComponentListsForDecl(
3723               VD, /*CurrentRegionOnly=*/true,
3724               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3725                  OpenMPClauseKind) { return true; }))
3726         continue;
3727       DeclRefExpr *DRE = buildDeclRefExpr(
3728           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3729           Cap.getLocation(), /*RefersToCapture=*/true);
3730       Visit(DRE);
3731     }
3732   }
isErrorFound() const3733   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3734   ArrayRef<Expr *> getImplicitFirstprivate() const {
3735     return ImplicitFirstprivate;
3736   }
getImplicitMap(OpenMPDefaultmapClauseKind Kind) const3737   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3738     return ImplicitMap[Kind];
3739   }
getVarsWithInheritedDSA() const3740   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3741     return VarsWithInheritedDSA;
3742   }
3743 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3744   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3745       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3746     // Process declare target link variables for the target directives.
3747     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3748       for (DeclRefExpr *E : Stack->getLinkGlobals())
3749         Visit(E);
3750     }
3751   }
3752 };
3753 } // namespace
3754 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3755 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3756   switch (DKind) {
3757   case OMPD_parallel:
3758   case OMPD_parallel_for:
3759   case OMPD_parallel_for_simd:
3760   case OMPD_parallel_sections:
3761   case OMPD_parallel_master:
3762   case OMPD_teams:
3763   case OMPD_teams_distribute:
3764   case OMPD_teams_distribute_simd: {
3765     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3766     QualType KmpInt32PtrTy =
3767         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3768     Sema::CapturedParamNameType Params[] = {
3769         std::make_pair(".global_tid.", KmpInt32PtrTy),
3770         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3771         std::make_pair(StringRef(), QualType()) // __context with shared vars
3772     };
3773     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3774                              Params);
3775     break;
3776   }
3777   case OMPD_target_teams:
3778   case OMPD_target_parallel:
3779   case OMPD_target_parallel_for:
3780   case OMPD_target_parallel_for_simd:
3781   case OMPD_target_teams_distribute:
3782   case OMPD_target_teams_distribute_simd: {
3783     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3784     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3785     QualType KmpInt32PtrTy =
3786         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3787     QualType Args[] = {VoidPtrTy};
3788     FunctionProtoType::ExtProtoInfo EPI;
3789     EPI.Variadic = true;
3790     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3791     Sema::CapturedParamNameType Params[] = {
3792         std::make_pair(".global_tid.", KmpInt32Ty),
3793         std::make_pair(".part_id.", KmpInt32PtrTy),
3794         std::make_pair(".privates.", VoidPtrTy),
3795         std::make_pair(
3796             ".copy_fn.",
3797             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3798         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3799         std::make_pair(StringRef(), QualType()) // __context with shared vars
3800     };
3801     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3802                              Params, /*OpenMPCaptureLevel=*/0);
3803     // Mark this captured region as inlined, because we don't use outlined
3804     // function directly.
3805     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3806         AlwaysInlineAttr::CreateImplicit(
3807             Context, {}, AttributeCommonInfo::AS_Keyword,
3808             AlwaysInlineAttr::Keyword_forceinline));
3809     Sema::CapturedParamNameType ParamsTarget[] = {
3810         std::make_pair(StringRef(), QualType()) // __context with shared vars
3811     };
3812     // Start a captured region for 'target' with no implicit parameters.
3813     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3814                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
3815     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3816         std::make_pair(".global_tid.", KmpInt32PtrTy),
3817         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3818         std::make_pair(StringRef(), QualType()) // __context with shared vars
3819     };
3820     // Start a captured region for 'teams' or 'parallel'.  Both regions have
3821     // the same implicit parameters.
3822     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3823                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3824     break;
3825   }
3826   case OMPD_target:
3827   case OMPD_target_simd: {
3828     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3829     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3830     QualType KmpInt32PtrTy =
3831         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3832     QualType Args[] = {VoidPtrTy};
3833     FunctionProtoType::ExtProtoInfo EPI;
3834     EPI.Variadic = true;
3835     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3836     Sema::CapturedParamNameType Params[] = {
3837         std::make_pair(".global_tid.", KmpInt32Ty),
3838         std::make_pair(".part_id.", KmpInt32PtrTy),
3839         std::make_pair(".privates.", VoidPtrTy),
3840         std::make_pair(
3841             ".copy_fn.",
3842             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3843         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3844         std::make_pair(StringRef(), QualType()) // __context with shared vars
3845     };
3846     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3847                              Params, /*OpenMPCaptureLevel=*/0);
3848     // Mark this captured region as inlined, because we don't use outlined
3849     // function directly.
3850     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3851         AlwaysInlineAttr::CreateImplicit(
3852             Context, {}, AttributeCommonInfo::AS_Keyword,
3853             AlwaysInlineAttr::Keyword_forceinline));
3854     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3855                              std::make_pair(StringRef(), QualType()),
3856                              /*OpenMPCaptureLevel=*/1);
3857     break;
3858   }
3859   case OMPD_atomic:
3860   case OMPD_critical:
3861   case OMPD_section:
3862   case OMPD_master:
3863     break;
3864   case OMPD_simd:
3865   case OMPD_for:
3866   case OMPD_for_simd:
3867   case OMPD_sections:
3868   case OMPD_single:
3869   case OMPD_taskgroup:
3870   case OMPD_distribute:
3871   case OMPD_distribute_simd:
3872   case OMPD_ordered:
3873   case OMPD_target_data: {
3874     Sema::CapturedParamNameType Params[] = {
3875         std::make_pair(StringRef(), QualType()) // __context with shared vars
3876     };
3877     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3878                              Params);
3879     break;
3880   }
3881   case OMPD_task: {
3882     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3883     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3884     QualType KmpInt32PtrTy =
3885         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3886     QualType Args[] = {VoidPtrTy};
3887     FunctionProtoType::ExtProtoInfo EPI;
3888     EPI.Variadic = true;
3889     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3890     Sema::CapturedParamNameType Params[] = {
3891         std::make_pair(".global_tid.", KmpInt32Ty),
3892         std::make_pair(".part_id.", KmpInt32PtrTy),
3893         std::make_pair(".privates.", VoidPtrTy),
3894         std::make_pair(
3895             ".copy_fn.",
3896             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3897         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3898         std::make_pair(StringRef(), QualType()) // __context with shared vars
3899     };
3900     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3901                              Params);
3902     // Mark this captured region as inlined, because we don't use outlined
3903     // function directly.
3904     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3905         AlwaysInlineAttr::CreateImplicit(
3906             Context, {}, AttributeCommonInfo::AS_Keyword,
3907             AlwaysInlineAttr::Keyword_forceinline));
3908     break;
3909   }
3910   case OMPD_taskloop:
3911   case OMPD_taskloop_simd:
3912   case OMPD_master_taskloop:
3913   case OMPD_master_taskloop_simd: {
3914     QualType KmpInt32Ty =
3915         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3916             .withConst();
3917     QualType KmpUInt64Ty =
3918         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3919             .withConst();
3920     QualType KmpInt64Ty =
3921         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3922             .withConst();
3923     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3924     QualType KmpInt32PtrTy =
3925         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3926     QualType Args[] = {VoidPtrTy};
3927     FunctionProtoType::ExtProtoInfo EPI;
3928     EPI.Variadic = true;
3929     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3930     Sema::CapturedParamNameType Params[] = {
3931         std::make_pair(".global_tid.", KmpInt32Ty),
3932         std::make_pair(".part_id.", KmpInt32PtrTy),
3933         std::make_pair(".privates.", VoidPtrTy),
3934         std::make_pair(
3935             ".copy_fn.",
3936             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3937         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3938         std::make_pair(".lb.", KmpUInt64Ty),
3939         std::make_pair(".ub.", KmpUInt64Ty),
3940         std::make_pair(".st.", KmpInt64Ty),
3941         std::make_pair(".liter.", KmpInt32Ty),
3942         std::make_pair(".reductions.", VoidPtrTy),
3943         std::make_pair(StringRef(), QualType()) // __context with shared vars
3944     };
3945     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3946                              Params);
3947     // Mark this captured region as inlined, because we don't use outlined
3948     // function directly.
3949     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3950         AlwaysInlineAttr::CreateImplicit(
3951             Context, {}, AttributeCommonInfo::AS_Keyword,
3952             AlwaysInlineAttr::Keyword_forceinline));
3953     break;
3954   }
3955   case OMPD_parallel_master_taskloop:
3956   case OMPD_parallel_master_taskloop_simd: {
3957     QualType KmpInt32Ty =
3958         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3959             .withConst();
3960     QualType KmpUInt64Ty =
3961         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3962             .withConst();
3963     QualType KmpInt64Ty =
3964         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3965             .withConst();
3966     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3967     QualType KmpInt32PtrTy =
3968         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3969     Sema::CapturedParamNameType ParamsParallel[] = {
3970         std::make_pair(".global_tid.", KmpInt32PtrTy),
3971         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3972         std::make_pair(StringRef(), QualType()) // __context with shared vars
3973     };
3974     // Start a captured region for 'parallel'.
3975     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3976                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
3977     QualType Args[] = {VoidPtrTy};
3978     FunctionProtoType::ExtProtoInfo EPI;
3979     EPI.Variadic = true;
3980     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3981     Sema::CapturedParamNameType Params[] = {
3982         std::make_pair(".global_tid.", KmpInt32Ty),
3983         std::make_pair(".part_id.", KmpInt32PtrTy),
3984         std::make_pair(".privates.", VoidPtrTy),
3985         std::make_pair(
3986             ".copy_fn.",
3987             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3988         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3989         std::make_pair(".lb.", KmpUInt64Ty),
3990         std::make_pair(".ub.", KmpUInt64Ty),
3991         std::make_pair(".st.", KmpInt64Ty),
3992         std::make_pair(".liter.", KmpInt32Ty),
3993         std::make_pair(".reductions.", VoidPtrTy),
3994         std::make_pair(StringRef(), QualType()) // __context with shared vars
3995     };
3996     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3997                              Params, /*OpenMPCaptureLevel=*/1);
3998     // Mark this captured region as inlined, because we don't use outlined
3999     // function directly.
4000     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4001         AlwaysInlineAttr::CreateImplicit(
4002             Context, {}, AttributeCommonInfo::AS_Keyword,
4003             AlwaysInlineAttr::Keyword_forceinline));
4004     break;
4005   }
4006   case OMPD_distribute_parallel_for_simd:
4007   case OMPD_distribute_parallel_for: {
4008     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4009     QualType KmpInt32PtrTy =
4010         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4011     Sema::CapturedParamNameType Params[] = {
4012         std::make_pair(".global_tid.", KmpInt32PtrTy),
4013         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4014         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4015         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4016         std::make_pair(StringRef(), QualType()) // __context with shared vars
4017     };
4018     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4019                              Params);
4020     break;
4021   }
4022   case OMPD_target_teams_distribute_parallel_for:
4023   case OMPD_target_teams_distribute_parallel_for_simd: {
4024     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4025     QualType KmpInt32PtrTy =
4026         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4027     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4028 
4029     QualType Args[] = {VoidPtrTy};
4030     FunctionProtoType::ExtProtoInfo EPI;
4031     EPI.Variadic = true;
4032     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4033     Sema::CapturedParamNameType Params[] = {
4034         std::make_pair(".global_tid.", KmpInt32Ty),
4035         std::make_pair(".part_id.", KmpInt32PtrTy),
4036         std::make_pair(".privates.", VoidPtrTy),
4037         std::make_pair(
4038             ".copy_fn.",
4039             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4040         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4041         std::make_pair(StringRef(), QualType()) // __context with shared vars
4042     };
4043     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4044                              Params, /*OpenMPCaptureLevel=*/0);
4045     // Mark this captured region as inlined, because we don't use outlined
4046     // function directly.
4047     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4048         AlwaysInlineAttr::CreateImplicit(
4049             Context, {}, AttributeCommonInfo::AS_Keyword,
4050             AlwaysInlineAttr::Keyword_forceinline));
4051     Sema::CapturedParamNameType ParamsTarget[] = {
4052         std::make_pair(StringRef(), QualType()) // __context with shared vars
4053     };
4054     // Start a captured region for 'target' with no implicit parameters.
4055     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4056                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4057 
4058     Sema::CapturedParamNameType ParamsTeams[] = {
4059         std::make_pair(".global_tid.", KmpInt32PtrTy),
4060         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4061         std::make_pair(StringRef(), QualType()) // __context with shared vars
4062     };
4063     // Start a captured region for 'target' with no implicit parameters.
4064     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4065                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4066 
4067     Sema::CapturedParamNameType ParamsParallel[] = {
4068         std::make_pair(".global_tid.", KmpInt32PtrTy),
4069         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4070         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4071         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4072         std::make_pair(StringRef(), QualType()) // __context with shared vars
4073     };
4074     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4075     // the same implicit parameters.
4076     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4077                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4078     break;
4079   }
4080 
4081   case OMPD_teams_distribute_parallel_for:
4082   case OMPD_teams_distribute_parallel_for_simd: {
4083     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4084     QualType KmpInt32PtrTy =
4085         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4086 
4087     Sema::CapturedParamNameType ParamsTeams[] = {
4088         std::make_pair(".global_tid.", KmpInt32PtrTy),
4089         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4090         std::make_pair(StringRef(), QualType()) // __context with shared vars
4091     };
4092     // Start a captured region for 'target' with no implicit parameters.
4093     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4094                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4095 
4096     Sema::CapturedParamNameType ParamsParallel[] = {
4097         std::make_pair(".global_tid.", KmpInt32PtrTy),
4098         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4099         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4100         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4101         std::make_pair(StringRef(), QualType()) // __context with shared vars
4102     };
4103     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4104     // the same implicit parameters.
4105     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4106                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4107     break;
4108   }
4109   case OMPD_target_update:
4110   case OMPD_target_enter_data:
4111   case OMPD_target_exit_data: {
4112     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4113     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4114     QualType KmpInt32PtrTy =
4115         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4116     QualType Args[] = {VoidPtrTy};
4117     FunctionProtoType::ExtProtoInfo EPI;
4118     EPI.Variadic = true;
4119     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4120     Sema::CapturedParamNameType Params[] = {
4121         std::make_pair(".global_tid.", KmpInt32Ty),
4122         std::make_pair(".part_id.", KmpInt32PtrTy),
4123         std::make_pair(".privates.", VoidPtrTy),
4124         std::make_pair(
4125             ".copy_fn.",
4126             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4127         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4128         std::make_pair(StringRef(), QualType()) // __context with shared vars
4129     };
4130     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4131                              Params);
4132     // Mark this captured region as inlined, because we don't use outlined
4133     // function directly.
4134     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4135         AlwaysInlineAttr::CreateImplicit(
4136             Context, {}, AttributeCommonInfo::AS_Keyword,
4137             AlwaysInlineAttr::Keyword_forceinline));
4138     break;
4139   }
4140   case OMPD_threadprivate:
4141   case OMPD_allocate:
4142   case OMPD_taskyield:
4143   case OMPD_barrier:
4144   case OMPD_taskwait:
4145   case OMPD_cancellation_point:
4146   case OMPD_cancel:
4147   case OMPD_flush:
4148   case OMPD_depobj:
4149   case OMPD_scan:
4150   case OMPD_declare_reduction:
4151   case OMPD_declare_mapper:
4152   case OMPD_declare_simd:
4153   case OMPD_declare_target:
4154   case OMPD_end_declare_target:
4155   case OMPD_requires:
4156   case OMPD_declare_variant:
4157   case OMPD_begin_declare_variant:
4158   case OMPD_end_declare_variant:
4159     llvm_unreachable("OpenMP Directive is not allowed");
4160   case OMPD_unknown:
4161   default:
4162     llvm_unreachable("Unknown OpenMP directive");
4163   }
4164   DSAStack->setContext(CurContext);
4165 }
4166 
getNumberOfConstructScopes(unsigned Level) const4167 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4168   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4169 }
4170 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4171 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4172   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4173   getOpenMPCaptureRegions(CaptureRegions, DKind);
4174   return CaptureRegions.size();
4175 }
4176 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4177 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4178                                              Expr *CaptureExpr, bool WithInit,
4179                                              bool AsExpression) {
4180   assert(CaptureExpr);
4181   ASTContext &C = S.getASTContext();
4182   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4183   QualType Ty = Init->getType();
4184   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4185     if (S.getLangOpts().CPlusPlus) {
4186       Ty = C.getLValueReferenceType(Ty);
4187     } else {
4188       Ty = C.getPointerType(Ty);
4189       ExprResult Res =
4190           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4191       if (!Res.isUsable())
4192         return nullptr;
4193       Init = Res.get();
4194     }
4195     WithInit = true;
4196   }
4197   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4198                                           CaptureExpr->getBeginLoc());
4199   if (!WithInit)
4200     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4201   S.CurContext->addHiddenDecl(CED);
4202   Sema::TentativeAnalysisScope Trap(S);
4203   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4204   return CED;
4205 }
4206 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4207 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4208                                  bool WithInit) {
4209   OMPCapturedExprDecl *CD;
4210   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4211     CD = cast<OMPCapturedExprDecl>(VD);
4212   else
4213     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4214                           /*AsExpression=*/false);
4215   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4216                           CaptureExpr->getExprLoc());
4217 }
4218 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4219 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4220   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4221   if (!Ref) {
4222     OMPCapturedExprDecl *CD = buildCaptureDecl(
4223         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4224         /*WithInit=*/true, /*AsExpression=*/true);
4225     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4226                            CaptureExpr->getExprLoc());
4227   }
4228   ExprResult Res = Ref;
4229   if (!S.getLangOpts().CPlusPlus &&
4230       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4231       Ref->getType()->isPointerType()) {
4232     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4233     if (!Res.isUsable())
4234       return ExprError();
4235   }
4236   return S.DefaultLvalueConversion(Res.get());
4237 }
4238 
4239 namespace {
4240 // OpenMP directives parsed in this section are represented as a
4241 // CapturedStatement with an associated statement.  If a syntax error
4242 // is detected during the parsing of the associated statement, the
4243 // compiler must abort processing and close the CapturedStatement.
4244 //
4245 // Combined directives such as 'target parallel' have more than one
4246 // nested CapturedStatements.  This RAII ensures that we unwind out
4247 // of all the nested CapturedStatements when an error is found.
4248 class CaptureRegionUnwinderRAII {
4249 private:
4250   Sema &S;
4251   bool &ErrorFound;
4252   OpenMPDirectiveKind DKind = OMPD_unknown;
4253 
4254 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4255   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4256                             OpenMPDirectiveKind DKind)
4257       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4258   ~CaptureRegionUnwinderRAII() {
4259     if (ErrorFound) {
4260       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4261       while (--ThisCaptureLevel >= 0)
4262         S.ActOnCapturedRegionError();
4263     }
4264   }
4265 };
4266 } // namespace
4267 
tryCaptureOpenMPLambdas(ValueDecl * V)4268 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4269   // Capture variables captured by reference in lambdas for target-based
4270   // directives.
4271   if (!CurContext->isDependentContext() &&
4272       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4273        isOpenMPTargetDataManagementDirective(
4274            DSAStack->getCurrentDirective()))) {
4275     QualType Type = V->getType();
4276     if (const auto *RD = Type.getCanonicalType()
4277                              .getNonReferenceType()
4278                              ->getAsCXXRecordDecl()) {
4279       bool SavedForceCaptureByReferenceInTargetExecutable =
4280           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4281       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4282           /*V=*/true);
4283       if (RD->isLambda()) {
4284         llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4285         FieldDecl *ThisCapture;
4286         RD->getCaptureFields(Captures, ThisCapture);
4287         for (const LambdaCapture &LC : RD->captures()) {
4288           if (LC.getCaptureKind() == LCK_ByRef) {
4289             VarDecl *VD = LC.getCapturedVar();
4290             DeclContext *VDC = VD->getDeclContext();
4291             if (!VDC->Encloses(CurContext))
4292               continue;
4293             MarkVariableReferenced(LC.getLocation(), VD);
4294           } else if (LC.getCaptureKind() == LCK_This) {
4295             QualType ThisTy = getCurrentThisType();
4296             if (!ThisTy.isNull() &&
4297                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4298               CheckCXXThisCapture(LC.getLocation());
4299           }
4300         }
4301       }
4302       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4303           SavedForceCaptureByReferenceInTargetExecutable);
4304     }
4305   }
4306 }
4307 
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4308 static bool checkOrderedOrderSpecified(Sema &S,
4309                                        const ArrayRef<OMPClause *> Clauses) {
4310   const OMPOrderedClause *Ordered = nullptr;
4311   const OMPOrderClause *Order = nullptr;
4312 
4313   for (const OMPClause *Clause : Clauses) {
4314     if (Clause->getClauseKind() == OMPC_ordered)
4315       Ordered = cast<OMPOrderedClause>(Clause);
4316     else if (Clause->getClauseKind() == OMPC_order) {
4317       Order = cast<OMPOrderClause>(Clause);
4318       if (Order->getKind() != OMPC_ORDER_concurrent)
4319         Order = nullptr;
4320     }
4321     if (Ordered && Order)
4322       break;
4323   }
4324 
4325   if (Ordered && Order) {
4326     S.Diag(Order->getKindKwLoc(),
4327            diag::err_omp_simple_clause_incompatible_with_ordered)
4328         << getOpenMPClauseName(OMPC_order)
4329         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4330         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4331     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4332         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4333     return true;
4334   }
4335   return false;
4336 }
4337 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4338 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4339                                       ArrayRef<OMPClause *> Clauses) {
4340   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4341       DSAStack->getCurrentDirective() == OMPD_critical ||
4342       DSAStack->getCurrentDirective() == OMPD_section ||
4343       DSAStack->getCurrentDirective() == OMPD_master)
4344     return S;
4345 
4346   bool ErrorFound = false;
4347   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4348       *this, ErrorFound, DSAStack->getCurrentDirective());
4349   if (!S.isUsable()) {
4350     ErrorFound = true;
4351     return StmtError();
4352   }
4353 
4354   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4355   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4356   OMPOrderedClause *OC = nullptr;
4357   OMPScheduleClause *SC = nullptr;
4358   SmallVector<const OMPLinearClause *, 4> LCs;
4359   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4360   // This is required for proper codegen.
4361   for (OMPClause *Clause : Clauses) {
4362     if (!LangOpts.OpenMPSimd &&
4363         isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4364         Clause->getClauseKind() == OMPC_in_reduction) {
4365       // Capture taskgroup task_reduction descriptors inside the tasking regions
4366       // with the corresponding in_reduction items.
4367       auto *IRC = cast<OMPInReductionClause>(Clause);
4368       for (Expr *E : IRC->taskgroup_descriptors())
4369         if (E)
4370           MarkDeclarationsReferencedInExpr(E);
4371     }
4372     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4373         Clause->getClauseKind() == OMPC_copyprivate ||
4374         (getLangOpts().OpenMPUseTLS &&
4375          getASTContext().getTargetInfo().isTLSSupported() &&
4376          Clause->getClauseKind() == OMPC_copyin)) {
4377       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4378       // Mark all variables in private list clauses as used in inner region.
4379       for (Stmt *VarRef : Clause->children()) {
4380         if (auto *E = cast_or_null<Expr>(VarRef)) {
4381           MarkDeclarationsReferencedInExpr(E);
4382         }
4383       }
4384       DSAStack->setForceVarCapturing(/*V=*/false);
4385     } else if (CaptureRegions.size() > 1 ||
4386                CaptureRegions.back() != OMPD_unknown) {
4387       if (auto *C = OMPClauseWithPreInit::get(Clause))
4388         PICs.push_back(C);
4389       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4390         if (Expr *E = C->getPostUpdateExpr())
4391           MarkDeclarationsReferencedInExpr(E);
4392       }
4393     }
4394     if (Clause->getClauseKind() == OMPC_schedule)
4395       SC = cast<OMPScheduleClause>(Clause);
4396     else if (Clause->getClauseKind() == OMPC_ordered)
4397       OC = cast<OMPOrderedClause>(Clause);
4398     else if (Clause->getClauseKind() == OMPC_linear)
4399       LCs.push_back(cast<OMPLinearClause>(Clause));
4400   }
4401   // Capture allocator expressions if used.
4402   for (Expr *E : DSAStack->getInnerAllocators())
4403     MarkDeclarationsReferencedInExpr(E);
4404   // OpenMP, 2.7.1 Loop Construct, Restrictions
4405   // The nonmonotonic modifier cannot be specified if an ordered clause is
4406   // specified.
4407   if (SC &&
4408       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4409        SC->getSecondScheduleModifier() ==
4410            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4411       OC) {
4412     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4413              ? SC->getFirstScheduleModifierLoc()
4414              : SC->getSecondScheduleModifierLoc(),
4415          diag::err_omp_simple_clause_incompatible_with_ordered)
4416         << getOpenMPClauseName(OMPC_schedule)
4417         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4418                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4419         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4420     ErrorFound = true;
4421   }
4422   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4423   // If an order(concurrent) clause is present, an ordered clause may not appear
4424   // on the same directive.
4425   if (checkOrderedOrderSpecified(*this, Clauses))
4426     ErrorFound = true;
4427   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4428     for (const OMPLinearClause *C : LCs) {
4429       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4430           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4431     }
4432     ErrorFound = true;
4433   }
4434   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4435       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4436       OC->getNumForLoops()) {
4437     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4438         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4439     ErrorFound = true;
4440   }
4441   if (ErrorFound) {
4442     return StmtError();
4443   }
4444   StmtResult SR = S;
4445   unsigned CompletedRegions = 0;
4446   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4447     // Mark all variables in private list clauses as used in inner region.
4448     // Required for proper codegen of combined directives.
4449     // TODO: add processing for other clauses.
4450     if (ThisCaptureRegion != OMPD_unknown) {
4451       for (const clang::OMPClauseWithPreInit *C : PICs) {
4452         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4453         // Find the particular capture region for the clause if the
4454         // directive is a combined one with multiple capture regions.
4455         // If the directive is not a combined one, the capture region
4456         // associated with the clause is OMPD_unknown and is generated
4457         // only once.
4458         if (CaptureRegion == ThisCaptureRegion ||
4459             CaptureRegion == OMPD_unknown) {
4460           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4461             for (Decl *D : DS->decls())
4462               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4463           }
4464         }
4465       }
4466     }
4467     if (ThisCaptureRegion == OMPD_target) {
4468       // Capture allocator traits in the target region. They are used implicitly
4469       // and, thus, are not captured by default.
4470       for (OMPClause *C : Clauses) {
4471         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4472           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4473                ++I) {
4474             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4475             if (Expr *E = D.AllocatorTraits)
4476               MarkDeclarationsReferencedInExpr(E);
4477           }
4478           continue;
4479         }
4480       }
4481     }
4482     if (++CompletedRegions == CaptureRegions.size())
4483       DSAStack->setBodyComplete();
4484     SR = ActOnCapturedRegionEnd(SR.get());
4485   }
4486   return SR;
4487 }
4488 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4489 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4490                               OpenMPDirectiveKind CancelRegion,
4491                               SourceLocation StartLoc) {
4492   // CancelRegion is only needed for cancel and cancellation_point.
4493   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4494     return false;
4495 
4496   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4497       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4498     return false;
4499 
4500   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4501       << getOpenMPDirectiveName(CancelRegion);
4502   return true;
4503 }
4504 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4505 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4506                                   OpenMPDirectiveKind CurrentRegion,
4507                                   const DeclarationNameInfo &CurrentName,
4508                                   OpenMPDirectiveKind CancelRegion,
4509                                   SourceLocation StartLoc) {
4510   if (Stack->getCurScope()) {
4511     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4512     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4513     bool NestingProhibited = false;
4514     bool CloseNesting = true;
4515     bool OrphanSeen = false;
4516     enum {
4517       NoRecommend,
4518       ShouldBeInParallelRegion,
4519       ShouldBeInOrderedRegion,
4520       ShouldBeInTargetRegion,
4521       ShouldBeInTeamsRegion,
4522       ShouldBeInLoopSimdRegion,
4523     } Recommend = NoRecommend;
4524     if (isOpenMPSimdDirective(ParentRegion) &&
4525         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4526          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4527           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4528           CurrentRegion != OMPD_scan))) {
4529       // OpenMP [2.16, Nesting of Regions]
4530       // OpenMP constructs may not be nested inside a simd region.
4531       // OpenMP [2.8.1,simd Construct, Restrictions]
4532       // An ordered construct with the simd clause is the only OpenMP
4533       // construct that can appear in the simd region.
4534       // Allowing a SIMD construct nested in another SIMD construct is an
4535       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4536       // message.
4537       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4538       // The only OpenMP constructs that can be encountered during execution of
4539       // a simd region are the atomic construct, the loop construct, the simd
4540       // construct and the ordered construct with the simd clause.
4541       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4542                                  ? diag::err_omp_prohibited_region_simd
4543                                  : diag::warn_omp_nesting_simd)
4544           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4545       return CurrentRegion != OMPD_simd;
4546     }
4547     if (ParentRegion == OMPD_atomic) {
4548       // OpenMP [2.16, Nesting of Regions]
4549       // OpenMP constructs may not be nested inside an atomic region.
4550       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4551       return true;
4552     }
4553     if (CurrentRegion == OMPD_section) {
4554       // OpenMP [2.7.2, sections Construct, Restrictions]
4555       // Orphaned section directives are prohibited. That is, the section
4556       // directives must appear within the sections construct and must not be
4557       // encountered elsewhere in the sections region.
4558       if (ParentRegion != OMPD_sections &&
4559           ParentRegion != OMPD_parallel_sections) {
4560         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4561             << (ParentRegion != OMPD_unknown)
4562             << getOpenMPDirectiveName(ParentRegion);
4563         return true;
4564       }
4565       return false;
4566     }
4567     // Allow some constructs (except teams and cancellation constructs) to be
4568     // orphaned (they could be used in functions, called from OpenMP regions
4569     // with the required preconditions).
4570     if (ParentRegion == OMPD_unknown &&
4571         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4572         CurrentRegion != OMPD_cancellation_point &&
4573         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4574       return false;
4575     if (CurrentRegion == OMPD_cancellation_point ||
4576         CurrentRegion == OMPD_cancel) {
4577       // OpenMP [2.16, Nesting of Regions]
4578       // A cancellation point construct for which construct-type-clause is
4579       // taskgroup must be nested inside a task construct. A cancellation
4580       // point construct for which construct-type-clause is not taskgroup must
4581       // be closely nested inside an OpenMP construct that matches the type
4582       // specified in construct-type-clause.
4583       // A cancel construct for which construct-type-clause is taskgroup must be
4584       // nested inside a task construct. A cancel construct for which
4585       // construct-type-clause is not taskgroup must be closely nested inside an
4586       // OpenMP construct that matches the type specified in
4587       // construct-type-clause.
4588       NestingProhibited =
4589           !((CancelRegion == OMPD_parallel &&
4590              (ParentRegion == OMPD_parallel ||
4591               ParentRegion == OMPD_target_parallel)) ||
4592             (CancelRegion == OMPD_for &&
4593              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4594               ParentRegion == OMPD_target_parallel_for ||
4595               ParentRegion == OMPD_distribute_parallel_for ||
4596               ParentRegion == OMPD_teams_distribute_parallel_for ||
4597               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4598             (CancelRegion == OMPD_taskgroup &&
4599              (ParentRegion == OMPD_task ||
4600               (SemaRef.getLangOpts().OpenMP >= 50 &&
4601                (ParentRegion == OMPD_taskloop ||
4602                 ParentRegion == OMPD_master_taskloop ||
4603                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4604             (CancelRegion == OMPD_sections &&
4605              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4606               ParentRegion == OMPD_parallel_sections)));
4607       OrphanSeen = ParentRegion == OMPD_unknown;
4608     } else if (CurrentRegion == OMPD_master) {
4609       // OpenMP [2.16, Nesting of Regions]
4610       // A master region may not be closely nested inside a worksharing,
4611       // atomic, or explicit task region.
4612       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4613                           isOpenMPTaskingDirective(ParentRegion);
4614     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4615       // OpenMP [2.16, Nesting of Regions]
4616       // A critical region may not be nested (closely or otherwise) inside a
4617       // critical region with the same name. Note that this restriction is not
4618       // sufficient to prevent deadlock.
4619       SourceLocation PreviousCriticalLoc;
4620       bool DeadLock = Stack->hasDirective(
4621           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4622                                               const DeclarationNameInfo &DNI,
4623                                               SourceLocation Loc) {
4624             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4625               PreviousCriticalLoc = Loc;
4626               return true;
4627             }
4628             return false;
4629           },
4630           false /* skip top directive */);
4631       if (DeadLock) {
4632         SemaRef.Diag(StartLoc,
4633                      diag::err_omp_prohibited_region_critical_same_name)
4634             << CurrentName.getName();
4635         if (PreviousCriticalLoc.isValid())
4636           SemaRef.Diag(PreviousCriticalLoc,
4637                        diag::note_omp_previous_critical_region);
4638         return true;
4639       }
4640     } else if (CurrentRegion == OMPD_barrier) {
4641       // OpenMP [2.16, Nesting of Regions]
4642       // A barrier region may not be closely nested inside a worksharing,
4643       // explicit task, critical, ordered, atomic, or master region.
4644       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4645                           isOpenMPTaskingDirective(ParentRegion) ||
4646                           ParentRegion == OMPD_master ||
4647                           ParentRegion == OMPD_parallel_master ||
4648                           ParentRegion == OMPD_critical ||
4649                           ParentRegion == OMPD_ordered;
4650     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4651                !isOpenMPParallelDirective(CurrentRegion) &&
4652                !isOpenMPTeamsDirective(CurrentRegion)) {
4653       // OpenMP [2.16, Nesting of Regions]
4654       // A worksharing region may not be closely nested inside a worksharing,
4655       // explicit task, critical, ordered, atomic, or master region.
4656       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4657                           isOpenMPTaskingDirective(ParentRegion) ||
4658                           ParentRegion == OMPD_master ||
4659                           ParentRegion == OMPD_parallel_master ||
4660                           ParentRegion == OMPD_critical ||
4661                           ParentRegion == OMPD_ordered;
4662       Recommend = ShouldBeInParallelRegion;
4663     } else if (CurrentRegion == OMPD_ordered) {
4664       // OpenMP [2.16, Nesting of Regions]
4665       // An ordered region may not be closely nested inside a critical,
4666       // atomic, or explicit task region.
4667       // An ordered region must be closely nested inside a loop region (or
4668       // parallel loop region) with an ordered clause.
4669       // OpenMP [2.8.1,simd Construct, Restrictions]
4670       // An ordered construct with the simd clause is the only OpenMP construct
4671       // that can appear in the simd region.
4672       NestingProhibited = ParentRegion == OMPD_critical ||
4673                           isOpenMPTaskingDirective(ParentRegion) ||
4674                           !(isOpenMPSimdDirective(ParentRegion) ||
4675                             Stack->isParentOrderedRegion());
4676       Recommend = ShouldBeInOrderedRegion;
4677     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4678       // OpenMP [2.16, Nesting of Regions]
4679       // If specified, a teams construct must be contained within a target
4680       // construct.
4681       NestingProhibited =
4682           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4683           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4684            ParentRegion != OMPD_target);
4685       OrphanSeen = ParentRegion == OMPD_unknown;
4686       Recommend = ShouldBeInTargetRegion;
4687     } else if (CurrentRegion == OMPD_scan) {
4688       // OpenMP [2.16, Nesting of Regions]
4689       // If specified, a teams construct must be contained within a target
4690       // construct.
4691       NestingProhibited =
4692           SemaRef.LangOpts.OpenMP < 50 ||
4693           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4694            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4695            ParentRegion != OMPD_parallel_for_simd);
4696       OrphanSeen = ParentRegion == OMPD_unknown;
4697       Recommend = ShouldBeInLoopSimdRegion;
4698     }
4699     if (!NestingProhibited &&
4700         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4701         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4702         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4703       // OpenMP [2.16, Nesting of Regions]
4704       // distribute, parallel, parallel sections, parallel workshare, and the
4705       // parallel loop and parallel loop SIMD constructs are the only OpenMP
4706       // constructs that can be closely nested in the teams region.
4707       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4708                           !isOpenMPDistributeDirective(CurrentRegion);
4709       Recommend = ShouldBeInParallelRegion;
4710     }
4711     if (!NestingProhibited &&
4712         isOpenMPNestingDistributeDirective(CurrentRegion)) {
4713       // OpenMP 4.5 [2.17 Nesting of Regions]
4714       // The region associated with the distribute construct must be strictly
4715       // nested inside a teams region
4716       NestingProhibited =
4717           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4718       Recommend = ShouldBeInTeamsRegion;
4719     }
4720     if (!NestingProhibited &&
4721         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4722          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4723       // OpenMP 4.5 [2.17 Nesting of Regions]
4724       // If a target, target update, target data, target enter data, or
4725       // target exit data construct is encountered during execution of a
4726       // target region, the behavior is unspecified.
4727       NestingProhibited = Stack->hasDirective(
4728           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4729                              SourceLocation) {
4730             if (isOpenMPTargetExecutionDirective(K)) {
4731               OffendingRegion = K;
4732               return true;
4733             }
4734             return false;
4735           },
4736           false /* don't skip top directive */);
4737       CloseNesting = false;
4738     }
4739     if (NestingProhibited) {
4740       if (OrphanSeen) {
4741         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4742             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4743       } else {
4744         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4745             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4746             << Recommend << getOpenMPDirectiveName(CurrentRegion);
4747       }
4748       return true;
4749     }
4750   }
4751   return false;
4752 }
4753 
4754 struct Kind2Unsigned {
4755   using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4756   unsigned operator()(argument_type DK) { return unsigned(DK); }
4757 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4758 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4759                            ArrayRef<OMPClause *> Clauses,
4760                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4761   bool ErrorFound = false;
4762   unsigned NamedModifiersNumber = 0;
4763   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4764   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4765   SmallVector<SourceLocation, 4> NameModifierLoc;
4766   for (const OMPClause *C : Clauses) {
4767     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4768       // At most one if clause without a directive-name-modifier can appear on
4769       // the directive.
4770       OpenMPDirectiveKind CurNM = IC->getNameModifier();
4771       if (FoundNameModifiers[CurNM]) {
4772         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4773             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4774             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4775         ErrorFound = true;
4776       } else if (CurNM != OMPD_unknown) {
4777         NameModifierLoc.push_back(IC->getNameModifierLoc());
4778         ++NamedModifiersNumber;
4779       }
4780       FoundNameModifiers[CurNM] = IC;
4781       if (CurNM == OMPD_unknown)
4782         continue;
4783       // Check if the specified name modifier is allowed for the current
4784       // directive.
4785       // At most one if clause with the particular directive-name-modifier can
4786       // appear on the directive.
4787       bool MatchFound = false;
4788       for (auto NM : AllowedNameModifiers) {
4789         if (CurNM == NM) {
4790           MatchFound = true;
4791           break;
4792         }
4793       }
4794       if (!MatchFound) {
4795         S.Diag(IC->getNameModifierLoc(),
4796                diag::err_omp_wrong_if_directive_name_modifier)
4797             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4798         ErrorFound = true;
4799       }
4800     }
4801   }
4802   // If any if clause on the directive includes a directive-name-modifier then
4803   // all if clauses on the directive must include a directive-name-modifier.
4804   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4805     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4806       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4807              diag::err_omp_no_more_if_clause);
4808     } else {
4809       std::string Values;
4810       std::string Sep(", ");
4811       unsigned AllowedCnt = 0;
4812       unsigned TotalAllowedNum =
4813           AllowedNameModifiers.size() - NamedModifiersNumber;
4814       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4815            ++Cnt) {
4816         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4817         if (!FoundNameModifiers[NM]) {
4818           Values += "'";
4819           Values += getOpenMPDirectiveName(NM);
4820           Values += "'";
4821           if (AllowedCnt + 2 == TotalAllowedNum)
4822             Values += " or ";
4823           else if (AllowedCnt + 1 != TotalAllowedNum)
4824             Values += Sep;
4825           ++AllowedCnt;
4826         }
4827       }
4828       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4829              diag::err_omp_unnamed_if_clause)
4830           << (TotalAllowedNum > 1) << Values;
4831     }
4832     for (SourceLocation Loc : NameModifierLoc) {
4833       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4834     }
4835     ErrorFound = true;
4836   }
4837   return ErrorFound;
4838 }
4839 
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)4840 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4841                                                    SourceLocation &ELoc,
4842                                                    SourceRange &ERange,
4843                                                    bool AllowArraySection) {
4844   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4845       RefExpr->containsUnexpandedParameterPack())
4846     return std::make_pair(nullptr, true);
4847 
4848   // OpenMP [3.1, C/C++]
4849   //  A list item is a variable name.
4850   // OpenMP  [2.9.3.3, Restrictions, p.1]
4851   //  A variable that is part of another variable (as an array or
4852   //  structure element) cannot appear in a private clause.
4853   RefExpr = RefExpr->IgnoreParens();
4854   enum {
4855     NoArrayExpr = -1,
4856     ArraySubscript = 0,
4857     OMPArraySection = 1
4858   } IsArrayExpr = NoArrayExpr;
4859   if (AllowArraySection) {
4860     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4861       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4862       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4863         Base = TempASE->getBase()->IgnoreParenImpCasts();
4864       RefExpr = Base;
4865       IsArrayExpr = ArraySubscript;
4866     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4867       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4868       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4869         Base = TempOASE->getBase()->IgnoreParenImpCasts();
4870       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4871         Base = TempASE->getBase()->IgnoreParenImpCasts();
4872       RefExpr = Base;
4873       IsArrayExpr = OMPArraySection;
4874     }
4875   }
4876   ELoc = RefExpr->getExprLoc();
4877   ERange = RefExpr->getSourceRange();
4878   RefExpr = RefExpr->IgnoreParenImpCasts();
4879   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4880   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4881   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4882       (S.getCurrentThisType().isNull() || !ME ||
4883        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4884        !isa<FieldDecl>(ME->getMemberDecl()))) {
4885     if (IsArrayExpr != NoArrayExpr) {
4886       S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4887                                                          << ERange;
4888     } else {
4889       S.Diag(ELoc,
4890              AllowArraySection
4891                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
4892                  : diag::err_omp_expected_var_name_member_expr)
4893           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4894     }
4895     return std::make_pair(nullptr, false);
4896   }
4897   return std::make_pair(
4898       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4899 }
4900 
4901 namespace {
4902 /// Checks if the allocator is used in uses_allocators clause to be allowed in
4903 /// target regions.
4904 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4905   DSAStackTy *S = nullptr;
4906 
4907 public:
VisitDeclRefExpr(const DeclRefExpr * E)4908   bool VisitDeclRefExpr(const DeclRefExpr *E) {
4909     return S->isUsesAllocatorsDecl(E->getDecl())
4910                .getValueOr(
4911                    DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4912            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4913   }
VisitStmt(const Stmt * S)4914   bool VisitStmt(const Stmt *S) {
4915     for (const Stmt *Child : S->children()) {
4916       if (Child && Visit(Child))
4917         return true;
4918     }
4919     return false;
4920   }
AllocatorChecker(DSAStackTy * S)4921   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4922 };
4923 } // namespace
4924 
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)4925 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4926                                  ArrayRef<OMPClause *> Clauses) {
4927   assert(!S.CurContext->isDependentContext() &&
4928          "Expected non-dependent context.");
4929   auto AllocateRange =
4930       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4931   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4932       DeclToCopy;
4933   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4934     return isOpenMPPrivate(C->getClauseKind());
4935   });
4936   for (OMPClause *Cl : PrivateRange) {
4937     MutableArrayRef<Expr *>::iterator I, It, Et;
4938     if (Cl->getClauseKind() == OMPC_private) {
4939       auto *PC = cast<OMPPrivateClause>(Cl);
4940       I = PC->private_copies().begin();
4941       It = PC->varlist_begin();
4942       Et = PC->varlist_end();
4943     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4944       auto *PC = cast<OMPFirstprivateClause>(Cl);
4945       I = PC->private_copies().begin();
4946       It = PC->varlist_begin();
4947       Et = PC->varlist_end();
4948     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4949       auto *PC = cast<OMPLastprivateClause>(Cl);
4950       I = PC->private_copies().begin();
4951       It = PC->varlist_begin();
4952       Et = PC->varlist_end();
4953     } else if (Cl->getClauseKind() == OMPC_linear) {
4954       auto *PC = cast<OMPLinearClause>(Cl);
4955       I = PC->privates().begin();
4956       It = PC->varlist_begin();
4957       Et = PC->varlist_end();
4958     } else if (Cl->getClauseKind() == OMPC_reduction) {
4959       auto *PC = cast<OMPReductionClause>(Cl);
4960       I = PC->privates().begin();
4961       It = PC->varlist_begin();
4962       Et = PC->varlist_end();
4963     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4964       auto *PC = cast<OMPTaskReductionClause>(Cl);
4965       I = PC->privates().begin();
4966       It = PC->varlist_begin();
4967       Et = PC->varlist_end();
4968     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4969       auto *PC = cast<OMPInReductionClause>(Cl);
4970       I = PC->privates().begin();
4971       It = PC->varlist_begin();
4972       Et = PC->varlist_end();
4973     } else {
4974       llvm_unreachable("Expected private clause.");
4975     }
4976     for (Expr *E : llvm::make_range(It, Et)) {
4977       if (!*I) {
4978         ++I;
4979         continue;
4980       }
4981       SourceLocation ELoc;
4982       SourceRange ERange;
4983       Expr *SimpleRefExpr = E;
4984       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4985                                 /*AllowArraySection=*/true);
4986       DeclToCopy.try_emplace(Res.first,
4987                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4988       ++I;
4989     }
4990   }
4991   for (OMPClause *C : AllocateRange) {
4992     auto *AC = cast<OMPAllocateClause>(C);
4993     if (S.getLangOpts().OpenMP >= 50 &&
4994         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4995         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4996         AC->getAllocator()) {
4997       Expr *Allocator = AC->getAllocator();
4998       // OpenMP, 2.12.5 target Construct
4999       // Memory allocators that do not appear in a uses_allocators clause cannot
5000       // appear as an allocator in an allocate clause or be used in the target
5001       // region unless a requires directive with the dynamic_allocators clause
5002       // is present in the same compilation unit.
5003       AllocatorChecker Checker(Stack);
5004       if (Checker.Visit(Allocator))
5005         S.Diag(Allocator->getExprLoc(),
5006                diag::err_omp_allocator_not_in_uses_allocators)
5007             << Allocator->getSourceRange();
5008     }
5009     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5010         getAllocatorKind(S, Stack, AC->getAllocator());
5011     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5012     // For task, taskloop or target directives, allocation requests to memory
5013     // allocators with the trait access set to thread result in unspecified
5014     // behavior.
5015     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5016         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5017          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5018       S.Diag(AC->getAllocator()->getExprLoc(),
5019              diag::warn_omp_allocate_thread_on_task_target_directive)
5020           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5021     }
5022     for (Expr *E : AC->varlists()) {
5023       SourceLocation ELoc;
5024       SourceRange ERange;
5025       Expr *SimpleRefExpr = E;
5026       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5027       ValueDecl *VD = Res.first;
5028       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5029       if (!isOpenMPPrivate(Data.CKind)) {
5030         S.Diag(E->getExprLoc(),
5031                diag::err_omp_expected_private_copy_for_allocate);
5032         continue;
5033       }
5034       VarDecl *PrivateVD = DeclToCopy[VD];
5035       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5036                                             AllocatorKind, AC->getAllocator()))
5037         continue;
5038       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5039                                 E->getSourceRange());
5040     }
5041   }
5042 }
5043 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5044 StmtResult Sema::ActOnOpenMPExecutableDirective(
5045     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5046     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5047     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5048   StmtResult Res = StmtError();
5049   // First check CancelRegion which is then used in checkNestingOfRegions.
5050   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5051       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5052                             StartLoc))
5053     return StmtError();
5054 
5055   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5056   VarsWithInheritedDSAType VarsWithInheritedDSA;
5057   bool ErrorFound = false;
5058   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5059   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5060       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) {
5061     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5062 
5063     // Check default data sharing attributes for referenced variables.
5064     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5065     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5066     Stmt *S = AStmt;
5067     while (--ThisCaptureLevel >= 0)
5068       S = cast<CapturedStmt>(S)->getCapturedStmt();
5069     DSAChecker.Visit(S);
5070     if (!isOpenMPTargetDataManagementDirective(Kind) &&
5071         !isOpenMPTaskingDirective(Kind)) {
5072       // Visit subcaptures to generate implicit clauses for captured vars.
5073       auto *CS = cast<CapturedStmt>(AStmt);
5074       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5075       getOpenMPCaptureRegions(CaptureRegions, Kind);
5076       // Ignore outer tasking regions for target directives.
5077       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5078         CS = cast<CapturedStmt>(CS->getCapturedStmt());
5079       DSAChecker.visitSubCaptures(CS);
5080     }
5081     if (DSAChecker.isErrorFound())
5082       return StmtError();
5083     // Generate list of implicitly defined firstprivate variables.
5084     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5085 
5086     SmallVector<Expr *, 4> ImplicitFirstprivates(
5087         DSAChecker.getImplicitFirstprivate().begin(),
5088         DSAChecker.getImplicitFirstprivate().end());
5089     SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5090     for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5091       ArrayRef<Expr *> ImplicitMap =
5092           DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5093       ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5094     }
5095     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5096     for (OMPClause *C : Clauses) {
5097       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5098         for (Expr *E : IRC->taskgroup_descriptors())
5099           if (E)
5100             ImplicitFirstprivates.emplace_back(E);
5101       }
5102       // OpenMP 5.0, 2.10.1 task Construct
5103       // [detach clause]... The event-handle will be considered as if it was
5104       // specified on a firstprivate clause.
5105       if (auto *DC = dyn_cast<OMPDetachClause>(C))
5106         ImplicitFirstprivates.push_back(DC->getEventHandler());
5107     }
5108     if (!ImplicitFirstprivates.empty()) {
5109       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5110               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5111               SourceLocation())) {
5112         ClausesWithImplicit.push_back(Implicit);
5113         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5114                      ImplicitFirstprivates.size();
5115       } else {
5116         ErrorFound = true;
5117       }
5118     }
5119     int ClauseKindCnt = -1;
5120     for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5121       ++ClauseKindCnt;
5122       if (ImplicitMap.empty())
5123         continue;
5124       CXXScopeSpec MapperIdScopeSpec;
5125       DeclarationNameInfo MapperId;
5126       auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5127       if (OMPClause *Implicit = ActOnOpenMPMapClause(
5128               llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5129               /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5130               ImplicitMap, OMPVarListLocTy())) {
5131         ClausesWithImplicit.emplace_back(Implicit);
5132         ErrorFound |=
5133             cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5134       } else {
5135         ErrorFound = true;
5136       }
5137     }
5138   }
5139 
5140   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5141   switch (Kind) {
5142   case OMPD_parallel:
5143     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5144                                        EndLoc);
5145     AllowedNameModifiers.push_back(OMPD_parallel);
5146     break;
5147   case OMPD_simd:
5148     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5149                                    VarsWithInheritedDSA);
5150     if (LangOpts.OpenMP >= 50)
5151       AllowedNameModifiers.push_back(OMPD_simd);
5152     break;
5153   case OMPD_for:
5154     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5155                                   VarsWithInheritedDSA);
5156     break;
5157   case OMPD_for_simd:
5158     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5159                                       EndLoc, VarsWithInheritedDSA);
5160     if (LangOpts.OpenMP >= 50)
5161       AllowedNameModifiers.push_back(OMPD_simd);
5162     break;
5163   case OMPD_sections:
5164     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5165                                        EndLoc);
5166     break;
5167   case OMPD_section:
5168     assert(ClausesWithImplicit.empty() &&
5169            "No clauses are allowed for 'omp section' directive");
5170     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5171     break;
5172   case OMPD_single:
5173     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5174                                      EndLoc);
5175     break;
5176   case OMPD_master:
5177     assert(ClausesWithImplicit.empty() &&
5178            "No clauses are allowed for 'omp master' directive");
5179     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5180     break;
5181   case OMPD_critical:
5182     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5183                                        StartLoc, EndLoc);
5184     break;
5185   case OMPD_parallel_for:
5186     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5187                                           EndLoc, VarsWithInheritedDSA);
5188     AllowedNameModifiers.push_back(OMPD_parallel);
5189     break;
5190   case OMPD_parallel_for_simd:
5191     Res = ActOnOpenMPParallelForSimdDirective(
5192         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5193     AllowedNameModifiers.push_back(OMPD_parallel);
5194     if (LangOpts.OpenMP >= 50)
5195       AllowedNameModifiers.push_back(OMPD_simd);
5196     break;
5197   case OMPD_parallel_master:
5198     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5199                                                StartLoc, EndLoc);
5200     AllowedNameModifiers.push_back(OMPD_parallel);
5201     break;
5202   case OMPD_parallel_sections:
5203     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5204                                                StartLoc, EndLoc);
5205     AllowedNameModifiers.push_back(OMPD_parallel);
5206     break;
5207   case OMPD_task:
5208     Res =
5209         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5210     AllowedNameModifiers.push_back(OMPD_task);
5211     break;
5212   case OMPD_taskyield:
5213     assert(ClausesWithImplicit.empty() &&
5214            "No clauses are allowed for 'omp taskyield' directive");
5215     assert(AStmt == nullptr &&
5216            "No associated statement allowed for 'omp taskyield' directive");
5217     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5218     break;
5219   case OMPD_barrier:
5220     assert(ClausesWithImplicit.empty() &&
5221            "No clauses are allowed for 'omp barrier' directive");
5222     assert(AStmt == nullptr &&
5223            "No associated statement allowed for 'omp barrier' directive");
5224     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5225     break;
5226   case OMPD_taskwait:
5227     assert(ClausesWithImplicit.empty() &&
5228            "No clauses are allowed for 'omp taskwait' directive");
5229     assert(AStmt == nullptr &&
5230            "No associated statement allowed for 'omp taskwait' directive");
5231     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5232     break;
5233   case OMPD_taskgroup:
5234     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5235                                         EndLoc);
5236     break;
5237   case OMPD_flush:
5238     assert(AStmt == nullptr &&
5239            "No associated statement allowed for 'omp flush' directive");
5240     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5241     break;
5242   case OMPD_depobj:
5243     assert(AStmt == nullptr &&
5244            "No associated statement allowed for 'omp depobj' directive");
5245     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5246     break;
5247   case OMPD_scan:
5248     assert(AStmt == nullptr &&
5249            "No associated statement allowed for 'omp scan' directive");
5250     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5251     break;
5252   case OMPD_ordered:
5253     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5254                                       EndLoc);
5255     break;
5256   case OMPD_atomic:
5257     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5258                                      EndLoc);
5259     break;
5260   case OMPD_teams:
5261     Res =
5262         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5263     break;
5264   case OMPD_target:
5265     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5266                                      EndLoc);
5267     AllowedNameModifiers.push_back(OMPD_target);
5268     break;
5269   case OMPD_target_parallel:
5270     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5271                                              StartLoc, EndLoc);
5272     AllowedNameModifiers.push_back(OMPD_target);
5273     AllowedNameModifiers.push_back(OMPD_parallel);
5274     break;
5275   case OMPD_target_parallel_for:
5276     Res = ActOnOpenMPTargetParallelForDirective(
5277         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5278     AllowedNameModifiers.push_back(OMPD_target);
5279     AllowedNameModifiers.push_back(OMPD_parallel);
5280     break;
5281   case OMPD_cancellation_point:
5282     assert(ClausesWithImplicit.empty() &&
5283            "No clauses are allowed for 'omp cancellation point' directive");
5284     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5285                                "cancellation point' directive");
5286     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5287     break;
5288   case OMPD_cancel:
5289     assert(AStmt == nullptr &&
5290            "No associated statement allowed for 'omp cancel' directive");
5291     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5292                                      CancelRegion);
5293     AllowedNameModifiers.push_back(OMPD_cancel);
5294     break;
5295   case OMPD_target_data:
5296     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5297                                          EndLoc);
5298     AllowedNameModifiers.push_back(OMPD_target_data);
5299     break;
5300   case OMPD_target_enter_data:
5301     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5302                                               EndLoc, AStmt);
5303     AllowedNameModifiers.push_back(OMPD_target_enter_data);
5304     break;
5305   case OMPD_target_exit_data:
5306     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5307                                              EndLoc, AStmt);
5308     AllowedNameModifiers.push_back(OMPD_target_exit_data);
5309     break;
5310   case OMPD_taskloop:
5311     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5312                                        EndLoc, VarsWithInheritedDSA);
5313     AllowedNameModifiers.push_back(OMPD_taskloop);
5314     break;
5315   case OMPD_taskloop_simd:
5316     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5317                                            EndLoc, VarsWithInheritedDSA);
5318     AllowedNameModifiers.push_back(OMPD_taskloop);
5319     if (LangOpts.OpenMP >= 50)
5320       AllowedNameModifiers.push_back(OMPD_simd);
5321     break;
5322   case OMPD_master_taskloop:
5323     Res = ActOnOpenMPMasterTaskLoopDirective(
5324         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5325     AllowedNameModifiers.push_back(OMPD_taskloop);
5326     break;
5327   case OMPD_master_taskloop_simd:
5328     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5329         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5330     AllowedNameModifiers.push_back(OMPD_taskloop);
5331     if (LangOpts.OpenMP >= 50)
5332       AllowedNameModifiers.push_back(OMPD_simd);
5333     break;
5334   case OMPD_parallel_master_taskloop:
5335     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5336         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5337     AllowedNameModifiers.push_back(OMPD_taskloop);
5338     AllowedNameModifiers.push_back(OMPD_parallel);
5339     break;
5340   case OMPD_parallel_master_taskloop_simd:
5341     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5342         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5343     AllowedNameModifiers.push_back(OMPD_taskloop);
5344     AllowedNameModifiers.push_back(OMPD_parallel);
5345     if (LangOpts.OpenMP >= 50)
5346       AllowedNameModifiers.push_back(OMPD_simd);
5347     break;
5348   case OMPD_distribute:
5349     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5350                                          EndLoc, VarsWithInheritedDSA);
5351     break;
5352   case OMPD_target_update:
5353     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5354                                            EndLoc, AStmt);
5355     AllowedNameModifiers.push_back(OMPD_target_update);
5356     break;
5357   case OMPD_distribute_parallel_for:
5358     Res = ActOnOpenMPDistributeParallelForDirective(
5359         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5360     AllowedNameModifiers.push_back(OMPD_parallel);
5361     break;
5362   case OMPD_distribute_parallel_for_simd:
5363     Res = ActOnOpenMPDistributeParallelForSimdDirective(
5364         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5365     AllowedNameModifiers.push_back(OMPD_parallel);
5366     if (LangOpts.OpenMP >= 50)
5367       AllowedNameModifiers.push_back(OMPD_simd);
5368     break;
5369   case OMPD_distribute_simd:
5370     Res = ActOnOpenMPDistributeSimdDirective(
5371         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5372     if (LangOpts.OpenMP >= 50)
5373       AllowedNameModifiers.push_back(OMPD_simd);
5374     break;
5375   case OMPD_target_parallel_for_simd:
5376     Res = ActOnOpenMPTargetParallelForSimdDirective(
5377         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5378     AllowedNameModifiers.push_back(OMPD_target);
5379     AllowedNameModifiers.push_back(OMPD_parallel);
5380     if (LangOpts.OpenMP >= 50)
5381       AllowedNameModifiers.push_back(OMPD_simd);
5382     break;
5383   case OMPD_target_simd:
5384     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5385                                          EndLoc, VarsWithInheritedDSA);
5386     AllowedNameModifiers.push_back(OMPD_target);
5387     if (LangOpts.OpenMP >= 50)
5388       AllowedNameModifiers.push_back(OMPD_simd);
5389     break;
5390   case OMPD_teams_distribute:
5391     Res = ActOnOpenMPTeamsDistributeDirective(
5392         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5393     break;
5394   case OMPD_teams_distribute_simd:
5395     Res = ActOnOpenMPTeamsDistributeSimdDirective(
5396         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5397     if (LangOpts.OpenMP >= 50)
5398       AllowedNameModifiers.push_back(OMPD_simd);
5399     break;
5400   case OMPD_teams_distribute_parallel_for_simd:
5401     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5402         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5403     AllowedNameModifiers.push_back(OMPD_parallel);
5404     if (LangOpts.OpenMP >= 50)
5405       AllowedNameModifiers.push_back(OMPD_simd);
5406     break;
5407   case OMPD_teams_distribute_parallel_for:
5408     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5409         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5410     AllowedNameModifiers.push_back(OMPD_parallel);
5411     break;
5412   case OMPD_target_teams:
5413     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5414                                           EndLoc);
5415     AllowedNameModifiers.push_back(OMPD_target);
5416     break;
5417   case OMPD_target_teams_distribute:
5418     Res = ActOnOpenMPTargetTeamsDistributeDirective(
5419         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5420     AllowedNameModifiers.push_back(OMPD_target);
5421     break;
5422   case OMPD_target_teams_distribute_parallel_for:
5423     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5424         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5425     AllowedNameModifiers.push_back(OMPD_target);
5426     AllowedNameModifiers.push_back(OMPD_parallel);
5427     break;
5428   case OMPD_target_teams_distribute_parallel_for_simd:
5429     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5430         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5431     AllowedNameModifiers.push_back(OMPD_target);
5432     AllowedNameModifiers.push_back(OMPD_parallel);
5433     if (LangOpts.OpenMP >= 50)
5434       AllowedNameModifiers.push_back(OMPD_simd);
5435     break;
5436   case OMPD_target_teams_distribute_simd:
5437     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5438         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5439     AllowedNameModifiers.push_back(OMPD_target);
5440     if (LangOpts.OpenMP >= 50)
5441       AllowedNameModifiers.push_back(OMPD_simd);
5442     break;
5443   case OMPD_declare_target:
5444   case OMPD_end_declare_target:
5445   case OMPD_threadprivate:
5446   case OMPD_allocate:
5447   case OMPD_declare_reduction:
5448   case OMPD_declare_mapper:
5449   case OMPD_declare_simd:
5450   case OMPD_requires:
5451   case OMPD_declare_variant:
5452   case OMPD_begin_declare_variant:
5453   case OMPD_end_declare_variant:
5454     llvm_unreachable("OpenMP Directive is not allowed");
5455   case OMPD_unknown:
5456   default:
5457     llvm_unreachable("Unknown OpenMP directive");
5458   }
5459 
5460   ErrorFound = Res.isInvalid() || ErrorFound;
5461 
5462   // Check variables in the clauses if default(none) or
5463   // default(firstprivate) was specified.
5464   if (DSAStack->getDefaultDSA() == DSA_none ||
5465       DSAStack->getDefaultDSA() == DSA_firstprivate) {
5466     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
5467     for (OMPClause *C : Clauses) {
5468       switch (C->getClauseKind()) {
5469       case OMPC_num_threads:
5470       case OMPC_dist_schedule:
5471         // Do not analyse if no parent teams directive.
5472         if (isOpenMPTeamsDirective(Kind))
5473           break;
5474         continue;
5475       case OMPC_if:
5476         if (isOpenMPTeamsDirective(Kind) &&
5477             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5478           break;
5479         if (isOpenMPParallelDirective(Kind) &&
5480             isOpenMPTaskLoopDirective(Kind) &&
5481             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5482           break;
5483         continue;
5484       case OMPC_schedule:
5485       case OMPC_detach:
5486         break;
5487       case OMPC_grainsize:
5488       case OMPC_num_tasks:
5489       case OMPC_final:
5490       case OMPC_priority:
5491         // Do not analyze if no parent parallel directive.
5492         if (isOpenMPParallelDirective(Kind))
5493           break;
5494         continue;
5495       case OMPC_ordered:
5496       case OMPC_device:
5497       case OMPC_num_teams:
5498       case OMPC_thread_limit:
5499       case OMPC_hint:
5500       case OMPC_collapse:
5501       case OMPC_safelen:
5502       case OMPC_simdlen:
5503       case OMPC_default:
5504       case OMPC_proc_bind:
5505       case OMPC_private:
5506       case OMPC_firstprivate:
5507       case OMPC_lastprivate:
5508       case OMPC_shared:
5509       case OMPC_reduction:
5510       case OMPC_task_reduction:
5511       case OMPC_in_reduction:
5512       case OMPC_linear:
5513       case OMPC_aligned:
5514       case OMPC_copyin:
5515       case OMPC_copyprivate:
5516       case OMPC_nowait:
5517       case OMPC_untied:
5518       case OMPC_mergeable:
5519       case OMPC_allocate:
5520       case OMPC_read:
5521       case OMPC_write:
5522       case OMPC_update:
5523       case OMPC_capture:
5524       case OMPC_seq_cst:
5525       case OMPC_acq_rel:
5526       case OMPC_acquire:
5527       case OMPC_release:
5528       case OMPC_relaxed:
5529       case OMPC_depend:
5530       case OMPC_threads:
5531       case OMPC_simd:
5532       case OMPC_map:
5533       case OMPC_nogroup:
5534       case OMPC_defaultmap:
5535       case OMPC_to:
5536       case OMPC_from:
5537       case OMPC_use_device_ptr:
5538       case OMPC_use_device_addr:
5539       case OMPC_is_device_ptr:
5540       case OMPC_nontemporal:
5541       case OMPC_order:
5542       case OMPC_destroy:
5543       case OMPC_inclusive:
5544       case OMPC_exclusive:
5545       case OMPC_uses_allocators:
5546       case OMPC_affinity:
5547         continue;
5548       case OMPC_allocator:
5549       case OMPC_flush:
5550       case OMPC_depobj:
5551       case OMPC_threadprivate:
5552       case OMPC_uniform:
5553       case OMPC_unknown:
5554       case OMPC_unified_address:
5555       case OMPC_unified_shared_memory:
5556       case OMPC_reverse_offload:
5557       case OMPC_dynamic_allocators:
5558       case OMPC_atomic_default_mem_order:
5559       case OMPC_device_type:
5560       case OMPC_match:
5561       default:
5562         llvm_unreachable("Unexpected clause");
5563       }
5564       for (Stmt *CC : C->children()) {
5565         if (CC)
5566           DSAChecker.Visit(CC);
5567       }
5568     }
5569     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5570       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5571   }
5572   for (const auto &P : VarsWithInheritedDSA) {
5573     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5574       continue;
5575     ErrorFound = true;
5576     if (DSAStack->getDefaultDSA() == DSA_none ||
5577         DSAStack->getDefaultDSA() == DSA_firstprivate) {
5578       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5579           << P.first << P.second->getSourceRange();
5580       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5581     } else if (getLangOpts().OpenMP >= 50) {
5582       Diag(P.second->getExprLoc(),
5583            diag::err_omp_defaultmap_no_attr_for_variable)
5584           << P.first << P.second->getSourceRange();
5585       Diag(DSAStack->getDefaultDSALocation(),
5586            diag::note_omp_defaultmap_attr_none);
5587     }
5588   }
5589 
5590   if (!AllowedNameModifiers.empty())
5591     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5592                  ErrorFound;
5593 
5594   if (ErrorFound)
5595     return StmtError();
5596 
5597   if (!CurContext->isDependentContext() &&
5598       isOpenMPTargetExecutionDirective(Kind) &&
5599       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5600         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5601         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5602         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5603     // Register target to DSA Stack.
5604     DSAStack->addTargetDirLocation(StartLoc);
5605   }
5606 
5607   return Res;
5608 }
5609 
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)5610 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5611     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5612     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5613     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5614     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5615   assert(Aligneds.size() == Alignments.size());
5616   assert(Linears.size() == LinModifiers.size());
5617   assert(Linears.size() == Steps.size());
5618   if (!DG || DG.get().isNull())
5619     return DeclGroupPtrTy();
5620 
5621   const int SimdId = 0;
5622   if (!DG.get().isSingleDecl()) {
5623     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5624         << SimdId;
5625     return DG;
5626   }
5627   Decl *ADecl = DG.get().getSingleDecl();
5628   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5629     ADecl = FTD->getTemplatedDecl();
5630 
5631   auto *FD = dyn_cast<FunctionDecl>(ADecl);
5632   if (!FD) {
5633     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5634     return DeclGroupPtrTy();
5635   }
5636 
5637   // OpenMP [2.8.2, declare simd construct, Description]
5638   // The parameter of the simdlen clause must be a constant positive integer
5639   // expression.
5640   ExprResult SL;
5641   if (Simdlen)
5642     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5643   // OpenMP [2.8.2, declare simd construct, Description]
5644   // The special this pointer can be used as if was one of the arguments to the
5645   // function in any of the linear, aligned, or uniform clauses.
5646   // The uniform clause declares one or more arguments to have an invariant
5647   // value for all concurrent invocations of the function in the execution of a
5648   // single SIMD loop.
5649   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5650   const Expr *UniformedLinearThis = nullptr;
5651   for (const Expr *E : Uniforms) {
5652     E = E->IgnoreParenImpCasts();
5653     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5654       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5655         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5656             FD->getParamDecl(PVD->getFunctionScopeIndex())
5657                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5658           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5659           continue;
5660         }
5661     if (isa<CXXThisExpr>(E)) {
5662       UniformedLinearThis = E;
5663       continue;
5664     }
5665     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5666         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5667   }
5668   // OpenMP [2.8.2, declare simd construct, Description]
5669   // The aligned clause declares that the object to which each list item points
5670   // is aligned to the number of bytes expressed in the optional parameter of
5671   // the aligned clause.
5672   // The special this pointer can be used as if was one of the arguments to the
5673   // function in any of the linear, aligned, or uniform clauses.
5674   // The type of list items appearing in the aligned clause must be array,
5675   // pointer, reference to array, or reference to pointer.
5676   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5677   const Expr *AlignedThis = nullptr;
5678   for (const Expr *E : Aligneds) {
5679     E = E->IgnoreParenImpCasts();
5680     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5681       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5682         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5683         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5684             FD->getParamDecl(PVD->getFunctionScopeIndex())
5685                     ->getCanonicalDecl() == CanonPVD) {
5686           // OpenMP  [2.8.1, simd construct, Restrictions]
5687           // A list-item cannot appear in more than one aligned clause.
5688           if (AlignedArgs.count(CanonPVD) > 0) {
5689             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5690                 << 1 << getOpenMPClauseName(OMPC_aligned)
5691                 << E->getSourceRange();
5692             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5693                  diag::note_omp_explicit_dsa)
5694                 << getOpenMPClauseName(OMPC_aligned);
5695             continue;
5696           }
5697           AlignedArgs[CanonPVD] = E;
5698           QualType QTy = PVD->getType()
5699                              .getNonReferenceType()
5700                              .getUnqualifiedType()
5701                              .getCanonicalType();
5702           const Type *Ty = QTy.getTypePtrOrNull();
5703           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5704             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5705                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5706             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5707           }
5708           continue;
5709         }
5710       }
5711     if (isa<CXXThisExpr>(E)) {
5712       if (AlignedThis) {
5713         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5714             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5715         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5716             << getOpenMPClauseName(OMPC_aligned);
5717       }
5718       AlignedThis = E;
5719       continue;
5720     }
5721     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5722         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5723   }
5724   // The optional parameter of the aligned clause, alignment, must be a constant
5725   // positive integer expression. If no optional parameter is specified,
5726   // implementation-defined default alignments for SIMD instructions on the
5727   // target platforms are assumed.
5728   SmallVector<const Expr *, 4> NewAligns;
5729   for (Expr *E : Alignments) {
5730     ExprResult Align;
5731     if (E)
5732       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5733     NewAligns.push_back(Align.get());
5734   }
5735   // OpenMP [2.8.2, declare simd construct, Description]
5736   // The linear clause declares one or more list items to be private to a SIMD
5737   // lane and to have a linear relationship with respect to the iteration space
5738   // of a loop.
5739   // The special this pointer can be used as if was one of the arguments to the
5740   // function in any of the linear, aligned, or uniform clauses.
5741   // When a linear-step expression is specified in a linear clause it must be
5742   // either a constant integer expression or an integer-typed parameter that is
5743   // specified in a uniform clause on the directive.
5744   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5745   const bool IsUniformedThis = UniformedLinearThis != nullptr;
5746   auto MI = LinModifiers.begin();
5747   for (const Expr *E : Linears) {
5748     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5749     ++MI;
5750     E = E->IgnoreParenImpCasts();
5751     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5752       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5753         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5754         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5755             FD->getParamDecl(PVD->getFunctionScopeIndex())
5756                     ->getCanonicalDecl() == CanonPVD) {
5757           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
5758           // A list-item cannot appear in more than one linear clause.
5759           if (LinearArgs.count(CanonPVD) > 0) {
5760             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5761                 << getOpenMPClauseName(OMPC_linear)
5762                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5763             Diag(LinearArgs[CanonPVD]->getExprLoc(),
5764                  diag::note_omp_explicit_dsa)
5765                 << getOpenMPClauseName(OMPC_linear);
5766             continue;
5767           }
5768           // Each argument can appear in at most one uniform or linear clause.
5769           if (UniformedArgs.count(CanonPVD) > 0) {
5770             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5771                 << getOpenMPClauseName(OMPC_linear)
5772                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5773             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5774                  diag::note_omp_explicit_dsa)
5775                 << getOpenMPClauseName(OMPC_uniform);
5776             continue;
5777           }
5778           LinearArgs[CanonPVD] = E;
5779           if (E->isValueDependent() || E->isTypeDependent() ||
5780               E->isInstantiationDependent() ||
5781               E->containsUnexpandedParameterPack())
5782             continue;
5783           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5784                                       PVD->getOriginalType(),
5785                                       /*IsDeclareSimd=*/true);
5786           continue;
5787         }
5788       }
5789     if (isa<CXXThisExpr>(E)) {
5790       if (UniformedLinearThis) {
5791         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5792             << getOpenMPClauseName(OMPC_linear)
5793             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5794             << E->getSourceRange();
5795         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5796             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5797                                                    : OMPC_linear);
5798         continue;
5799       }
5800       UniformedLinearThis = E;
5801       if (E->isValueDependent() || E->isTypeDependent() ||
5802           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5803         continue;
5804       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5805                                   E->getType(), /*IsDeclareSimd=*/true);
5806       continue;
5807     }
5808     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5809         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5810   }
5811   Expr *Step = nullptr;
5812   Expr *NewStep = nullptr;
5813   SmallVector<Expr *, 4> NewSteps;
5814   for (Expr *E : Steps) {
5815     // Skip the same step expression, it was checked already.
5816     if (Step == E || !E) {
5817       NewSteps.push_back(E ? NewStep : nullptr);
5818       continue;
5819     }
5820     Step = E;
5821     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5822       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5823         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5824         if (UniformedArgs.count(CanonPVD) == 0) {
5825           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5826               << Step->getSourceRange();
5827         } else if (E->isValueDependent() || E->isTypeDependent() ||
5828                    E->isInstantiationDependent() ||
5829                    E->containsUnexpandedParameterPack() ||
5830                    CanonPVD->getType()->hasIntegerRepresentation()) {
5831           NewSteps.push_back(Step);
5832         } else {
5833           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5834               << Step->getSourceRange();
5835         }
5836         continue;
5837       }
5838     NewStep = Step;
5839     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5840         !Step->isInstantiationDependent() &&
5841         !Step->containsUnexpandedParameterPack()) {
5842       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5843                     .get();
5844       if (NewStep)
5845         NewStep =
5846             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
5847     }
5848     NewSteps.push_back(NewStep);
5849   }
5850   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5851       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5852       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5853       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5854       const_cast<Expr **>(Linears.data()), Linears.size(),
5855       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5856       NewSteps.data(), NewSteps.size(), SR);
5857   ADecl->addAttr(NewAttr);
5858   return DG;
5859 }
5860 
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)5861 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5862                          QualType NewType) {
5863   assert(NewType->isFunctionProtoType() &&
5864          "Expected function type with prototype.");
5865   assert(FD->getType()->isFunctionNoProtoType() &&
5866          "Expected function with type with no prototype.");
5867   assert(FDWithProto->getType()->isFunctionProtoType() &&
5868          "Expected function with prototype.");
5869   // Synthesize parameters with the same types.
5870   FD->setType(NewType);
5871   SmallVector<ParmVarDecl *, 16> Params;
5872   for (const ParmVarDecl *P : FDWithProto->parameters()) {
5873     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5874                                       SourceLocation(), nullptr, P->getType(),
5875                                       /*TInfo=*/nullptr, SC_None, nullptr);
5876     Param->setScopeInfo(0, Params.size());
5877     Param->setImplicit();
5878     Params.push_back(Param);
5879   }
5880 
5881   FD->setParams(Params);
5882 }
5883 
OMPDeclareVariantScope(OMPTraitInfo & TI)5884 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
5885     : TI(&TI), NameSuffix(TI.getMangledName()) {}
5886 
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)5887 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
5888     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
5889     SmallVectorImpl<FunctionDecl *> &Bases) {
5890   if (!D.getIdentifier())
5891     return;
5892 
5893   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5894 
5895   // Template specialization is an extension, check if we do it.
5896   bool IsTemplated = !TemplateParamLists.empty();
5897   if (IsTemplated &
5898       !DVScope.TI->isExtensionActive(
5899           llvm::omp::TraitProperty::implementation_extension_allow_templates))
5900     return;
5901 
5902   IdentifierInfo *BaseII = D.getIdentifier();
5903   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
5904                       LookupOrdinaryName);
5905   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
5906 
5907   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
5908   QualType FType = TInfo->getType();
5909 
5910   bool IsConstexpr =
5911       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
5912   bool IsConsteval =
5913       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
5914 
5915   for (auto *Candidate : Lookup) {
5916     auto *CandidateDecl = Candidate->getUnderlyingDecl();
5917     FunctionDecl *UDecl = nullptr;
5918     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
5919       UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
5920     else if (!IsTemplated)
5921       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
5922     if (!UDecl)
5923       continue;
5924 
5925     // Don't specialize constexpr/consteval functions with
5926     // non-constexpr/consteval functions.
5927     if (UDecl->isConstexpr() && !IsConstexpr)
5928       continue;
5929     if (UDecl->isConsteval() && !IsConsteval)
5930       continue;
5931 
5932     QualType UDeclTy = UDecl->getType();
5933     if (!UDeclTy->isDependentType()) {
5934       QualType NewType = Context.mergeFunctionTypes(
5935           FType, UDeclTy, /* OfBlockPointer */ false,
5936           /* Unqualified */ false, /* AllowCXX */ true);
5937       if (NewType.isNull())
5938         continue;
5939     }
5940 
5941     // Found a base!
5942     Bases.push_back(UDecl);
5943   }
5944 
5945   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
5946       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
5947   // If no base was found we create a declaration that we use as base.
5948   if (Bases.empty() && UseImplicitBase) {
5949     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
5950     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
5951     BaseD->setImplicit(true);
5952     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
5953       Bases.push_back(BaseTemplD->getTemplatedDecl());
5954     else
5955       Bases.push_back(cast<FunctionDecl>(BaseD));
5956   }
5957 
5958   std::string MangledName;
5959   MangledName += D.getIdentifier()->getName();
5960   MangledName += getOpenMPVariantManglingSeparatorStr();
5961   MangledName += DVScope.NameSuffix;
5962   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
5963 
5964   VariantII.setMangledOpenMPVariantName(true);
5965   D.SetIdentifier(&VariantII, D.getBeginLoc());
5966 }
5967 
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)5968 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
5969     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
5970   // Do not mark function as is used to prevent its emission if this is the
5971   // only place where it is used.
5972   EnterExpressionEvaluationContext Unevaluated(
5973       *this, Sema::ExpressionEvaluationContext::Unevaluated);
5974 
5975   FunctionDecl *FD = nullptr;
5976   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
5977     FD = UTemplDecl->getTemplatedDecl();
5978   else
5979     FD = cast<FunctionDecl>(D);
5980   auto *VariantFuncRef = DeclRefExpr::Create(
5981       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
5982       /* RefersToEnclosingVariableOrCapture */ false,
5983       /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
5984 
5985   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5986   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
5987       Context, VariantFuncRef, DVScope.TI);
5988   for (FunctionDecl *BaseFD : Bases)
5989     BaseFD->addAttr(OMPDeclareVariantA);
5990 }
5991 
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)5992 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
5993                                  SourceLocation LParenLoc,
5994                                  MultiExprArg ArgExprs,
5995                                  SourceLocation RParenLoc, Expr *ExecConfig) {
5996   // The common case is a regular call we do not want to specialize at all. Try
5997   // to make that case fast by bailing early.
5998   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
5999   if (!CE)
6000     return Call;
6001 
6002   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6003   if (!CalleeFnDecl)
6004     return Call;
6005 
6006   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6007     return Call;
6008 
6009   ASTContext &Context = getASTContext();
6010   std::function<void(StringRef)> DiagUnknownTrait = [this,
6011                                                      CE](StringRef ISATrait) {
6012     // TODO Track the selector locations in a way that is accessible here to
6013     // improve the diagnostic location.
6014     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6015         << ISATrait;
6016   };
6017   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6018                           getCurFunctionDecl());
6019 
6020   QualType CalleeFnType = CalleeFnDecl->getType();
6021 
6022   SmallVector<Expr *, 4> Exprs;
6023   SmallVector<VariantMatchInfo, 4> VMIs;
6024   while (CalleeFnDecl) {
6025     for (OMPDeclareVariantAttr *A :
6026          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6027       Expr *VariantRef = A->getVariantFuncRef();
6028 
6029       VariantMatchInfo VMI;
6030       OMPTraitInfo &TI = A->getTraitInfo();
6031       TI.getAsVariantMatchInfo(Context, VMI);
6032       if (!isVariantApplicableInContext(VMI, OMPCtx,
6033                                         /* DeviceSetOnly */ false))
6034         continue;
6035 
6036       VMIs.push_back(VMI);
6037       Exprs.push_back(VariantRef);
6038     }
6039 
6040     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6041   }
6042 
6043   ExprResult NewCall;
6044   do {
6045     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6046     if (BestIdx < 0)
6047       return Call;
6048     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6049     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6050 
6051     {
6052       // Try to build a (member) call expression for the current best applicable
6053       // variant expression. We allow this to fail in which case we continue
6054       // with the next best variant expression. The fail case is part of the
6055       // implementation defined behavior in the OpenMP standard when it talks
6056       // about what differences in the function prototypes: "Any differences
6057       // that the specific OpenMP context requires in the prototype of the
6058       // variant from the base function prototype are implementation defined."
6059       // This wording is there to allow the specialized variant to have a
6060       // different type than the base function. This is intended and OK but if
6061       // we cannot create a call the difference is not in the "implementation
6062       // defined range" we allow.
6063       Sema::TentativeAnalysisScope Trap(*this);
6064 
6065       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6066         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6067         BestExpr = MemberExpr::CreateImplicit(
6068             Context, MemberCall->getImplicitObjectArgument(),
6069             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6070             MemberCall->getValueKind(), MemberCall->getObjectKind());
6071       }
6072       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6073                               ExecConfig);
6074       if (NewCall.isUsable()) {
6075         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6076           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6077           QualType NewType = Context.mergeFunctionTypes(
6078               CalleeFnType, NewCalleeFnDecl->getType(),
6079               /* OfBlockPointer */ false,
6080               /* Unqualified */ false, /* AllowCXX */ true);
6081           if (!NewType.isNull())
6082             break;
6083           // Don't use the call if the function type was not compatible.
6084           NewCall = nullptr;
6085         }
6086       }
6087     }
6088 
6089     VMIs.erase(VMIs.begin() + BestIdx);
6090     Exprs.erase(Exprs.begin() + BestIdx);
6091   } while (!VMIs.empty());
6092 
6093   if (!NewCall.isUsable())
6094     return Call;
6095   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6096 }
6097 
6098 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6099 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6100                                         Expr *VariantRef, OMPTraitInfo &TI,
6101                                         SourceRange SR) {
6102   if (!DG || DG.get().isNull())
6103     return None;
6104 
6105   const int VariantId = 1;
6106   // Must be applied only to single decl.
6107   if (!DG.get().isSingleDecl()) {
6108     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6109         << VariantId << SR;
6110     return None;
6111   }
6112   Decl *ADecl = DG.get().getSingleDecl();
6113   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6114     ADecl = FTD->getTemplatedDecl();
6115 
6116   // Decl must be a function.
6117   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6118   if (!FD) {
6119     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6120         << VariantId << SR;
6121     return None;
6122   }
6123 
6124   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6125     return FD->hasAttrs() &&
6126            (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6127             FD->hasAttr<TargetAttr>());
6128   };
6129   // OpenMP is not compatible with CPU-specific attributes.
6130   if (HasMultiVersionAttributes(FD)) {
6131     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6132         << SR;
6133     return None;
6134   }
6135 
6136   // Allow #pragma omp declare variant only if the function is not used.
6137   if (FD->isUsed(false))
6138     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6139         << FD->getLocation();
6140 
6141   // Check if the function was emitted already.
6142   const FunctionDecl *Definition;
6143   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6144       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6145     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6146         << FD->getLocation();
6147 
6148   // The VariantRef must point to function.
6149   if (!VariantRef) {
6150     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6151     return None;
6152   }
6153 
6154   auto ShouldDelayChecks = [](Expr *&E, bool) {
6155     return E && (E->isTypeDependent() || E->isValueDependent() ||
6156                  E->containsUnexpandedParameterPack() ||
6157                  E->isInstantiationDependent());
6158   };
6159   // Do not check templates, wait until instantiation.
6160   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6161       TI.anyScoreOrCondition(ShouldDelayChecks))
6162     return std::make_pair(FD, VariantRef);
6163 
6164   // Deal with non-constant score and user condition expressions.
6165   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6166                                                      bool IsScore) -> bool {
6167     if (!E || E->isIntegerConstantExpr(Context))
6168       return false;
6169 
6170     if (IsScore) {
6171       // We warn on non-constant scores and pretend they were not present.
6172       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6173           << E;
6174       E = nullptr;
6175     } else {
6176       // We could replace a non-constant user condition with "false" but we
6177       // will soon need to handle these anyway for the dynamic version of
6178       // OpenMP context selectors.
6179       Diag(E->getExprLoc(),
6180            diag::err_omp_declare_variant_user_condition_not_constant)
6181           << E;
6182     }
6183     return true;
6184   };
6185   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6186     return None;
6187 
6188   // Convert VariantRef expression to the type of the original function to
6189   // resolve possible conflicts.
6190   ExprResult VariantRefCast = VariantRef;
6191   if (LangOpts.CPlusPlus) {
6192     QualType FnPtrType;
6193     auto *Method = dyn_cast<CXXMethodDecl>(FD);
6194     if (Method && !Method->isStatic()) {
6195       const Type *ClassType =
6196           Context.getTypeDeclType(Method->getParent()).getTypePtr();
6197       FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6198       ExprResult ER;
6199       {
6200         // Build adrr_of unary op to correctly handle type checks for member
6201         // functions.
6202         Sema::TentativeAnalysisScope Trap(*this);
6203         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6204                                   VariantRef);
6205       }
6206       if (!ER.isUsable()) {
6207         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6208             << VariantId << VariantRef->getSourceRange();
6209         return None;
6210       }
6211       VariantRef = ER.get();
6212     } else {
6213       FnPtrType = Context.getPointerType(FD->getType());
6214     }
6215     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6216     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6217       ImplicitConversionSequence ICS = TryImplicitConversion(
6218           VariantRef, FnPtrType.getUnqualifiedType(),
6219           /*SuppressUserConversions=*/false, AllowedExplicit::None,
6220           /*InOverloadResolution=*/false,
6221           /*CStyle=*/false,
6222           /*AllowObjCWritebackConversion=*/false);
6223       if (ICS.isFailure()) {
6224         Diag(VariantRef->getExprLoc(),
6225              diag::err_omp_declare_variant_incompat_types)
6226             << VariantRef->getType()
6227             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6228             << VariantRef->getSourceRange();
6229         return None;
6230       }
6231       VariantRefCast = PerformImplicitConversion(
6232           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6233       if (!VariantRefCast.isUsable())
6234         return None;
6235     }
6236     // Drop previously built artificial addr_of unary op for member functions.
6237     if (Method && !Method->isStatic()) {
6238       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6239       if (auto *UO = dyn_cast<UnaryOperator>(
6240               PossibleAddrOfVariantRef->IgnoreImplicit()))
6241         VariantRefCast = UO->getSubExpr();
6242     }
6243   }
6244 
6245   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6246   if (!ER.isUsable() ||
6247       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6248     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6249         << VariantId << VariantRef->getSourceRange();
6250     return None;
6251   }
6252 
6253   // The VariantRef must point to function.
6254   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6255   if (!DRE) {
6256     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6257         << VariantId << VariantRef->getSourceRange();
6258     return None;
6259   }
6260   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6261   if (!NewFD) {
6262     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6263         << VariantId << VariantRef->getSourceRange();
6264     return None;
6265   }
6266 
6267   // Check if function types are compatible in C.
6268   if (!LangOpts.CPlusPlus) {
6269     QualType NewType =
6270         Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6271     if (NewType.isNull()) {
6272       Diag(VariantRef->getExprLoc(),
6273            diag::err_omp_declare_variant_incompat_types)
6274           << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6275       return None;
6276     }
6277     if (NewType->isFunctionProtoType()) {
6278       if (FD->getType()->isFunctionNoProtoType())
6279         setPrototype(*this, FD, NewFD, NewType);
6280       else if (NewFD->getType()->isFunctionNoProtoType())
6281         setPrototype(*this, NewFD, FD, NewType);
6282     }
6283   }
6284 
6285   // Check if variant function is not marked with declare variant directive.
6286   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6287     Diag(VariantRef->getExprLoc(),
6288          diag::warn_omp_declare_variant_marked_as_declare_variant)
6289         << VariantRef->getSourceRange();
6290     SourceRange SR =
6291         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6292     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6293     return None;
6294   }
6295 
6296   enum DoesntSupport {
6297     VirtFuncs = 1,
6298     Constructors = 3,
6299     Destructors = 4,
6300     DeletedFuncs = 5,
6301     DefaultedFuncs = 6,
6302     ConstexprFuncs = 7,
6303     ConstevalFuncs = 8,
6304   };
6305   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6306     if (CXXFD->isVirtual()) {
6307       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6308           << VirtFuncs;
6309       return None;
6310     }
6311 
6312     if (isa<CXXConstructorDecl>(FD)) {
6313       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6314           << Constructors;
6315       return None;
6316     }
6317 
6318     if (isa<CXXDestructorDecl>(FD)) {
6319       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6320           << Destructors;
6321       return None;
6322     }
6323   }
6324 
6325   if (FD->isDeleted()) {
6326     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6327         << DeletedFuncs;
6328     return None;
6329   }
6330 
6331   if (FD->isDefaulted()) {
6332     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6333         << DefaultedFuncs;
6334     return None;
6335   }
6336 
6337   if (FD->isConstexpr()) {
6338     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6339         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6340     return None;
6341   }
6342 
6343   // Check general compatibility.
6344   if (areMultiversionVariantFunctionsCompatible(
6345           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6346           PartialDiagnosticAt(SourceLocation(),
6347                               PartialDiagnostic::NullDiagnostic()),
6348           PartialDiagnosticAt(
6349               VariantRef->getExprLoc(),
6350               PDiag(diag::err_omp_declare_variant_doesnt_support)),
6351           PartialDiagnosticAt(VariantRef->getExprLoc(),
6352                               PDiag(diag::err_omp_declare_variant_diff)
6353                                   << FD->getLocation()),
6354           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6355           /*CLinkageMayDiffer=*/true))
6356     return None;
6357   return std::make_pair(FD, cast<Expr>(DRE));
6358 }
6359 
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6360 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6361                                               Expr *VariantRef,
6362                                               OMPTraitInfo &TI,
6363                                               SourceRange SR) {
6364   auto *NewAttr =
6365       OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6366   FD->addAttr(NewAttr);
6367 }
6368 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6369 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6370                                               Stmt *AStmt,
6371                                               SourceLocation StartLoc,
6372                                               SourceLocation EndLoc) {
6373   if (!AStmt)
6374     return StmtError();
6375 
6376   auto *CS = cast<CapturedStmt>(AStmt);
6377   // 1.2.2 OpenMP Language Terminology
6378   // Structured block - An executable statement with a single entry at the
6379   // top and a single exit at the bottom.
6380   // The point of exit cannot be a branch out of the structured block.
6381   // longjmp() and throw() must not violate the entry/exit criteria.
6382   CS->getCapturedDecl()->setNothrow();
6383 
6384   setFunctionHasBranchProtectedScope();
6385 
6386   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6387                                       DSAStack->getTaskgroupReductionRef(),
6388                                       DSAStack->isCancelRegion());
6389 }
6390 
6391 namespace {
6392 /// Iteration space of a single for loop.
6393 struct LoopIterationSpace final {
6394   /// True if the condition operator is the strict compare operator (<, > or
6395   /// !=).
6396   bool IsStrictCompare = false;
6397   /// Condition of the loop.
6398   Expr *PreCond = nullptr;
6399   /// This expression calculates the number of iterations in the loop.
6400   /// It is always possible to calculate it before starting the loop.
6401   Expr *NumIterations = nullptr;
6402   /// The loop counter variable.
6403   Expr *CounterVar = nullptr;
6404   /// Private loop counter variable.
6405   Expr *PrivateCounterVar = nullptr;
6406   /// This is initializer for the initial value of #CounterVar.
6407   Expr *CounterInit = nullptr;
6408   /// This is step for the #CounterVar used to generate its update:
6409   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6410   Expr *CounterStep = nullptr;
6411   /// Should step be subtracted?
6412   bool Subtract = false;
6413   /// Source range of the loop init.
6414   SourceRange InitSrcRange;
6415   /// Source range of the loop condition.
6416   SourceRange CondSrcRange;
6417   /// Source range of the loop increment.
6418   SourceRange IncSrcRange;
6419   /// Minimum value that can have the loop control variable. Used to support
6420   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6421   /// since only such variables can be used in non-loop invariant expressions.
6422   Expr *MinValue = nullptr;
6423   /// Maximum value that can have the loop control variable. Used to support
6424   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6425   /// since only such variables can be used in non-loop invariant expressions.
6426   Expr *MaxValue = nullptr;
6427   /// true, if the lower bound depends on the outer loop control var.
6428   bool IsNonRectangularLB = false;
6429   /// true, if the upper bound depends on the outer loop control var.
6430   bool IsNonRectangularUB = false;
6431   /// Index of the loop this loop depends on and forms non-rectangular loop
6432   /// nest.
6433   unsigned LoopDependentIdx = 0;
6434   /// Final condition for the non-rectangular loop nest support. It is used to
6435   /// check that the number of iterations for this particular counter must be
6436   /// finished.
6437   Expr *FinalCondition = nullptr;
6438 };
6439 
6440 /// Helper class for checking canonical form of the OpenMP loops and
6441 /// extracting iteration space of each loop in the loop nest, that will be used
6442 /// for IR generation.
6443 class OpenMPIterationSpaceChecker {
6444   /// Reference to Sema.
6445   Sema &SemaRef;
6446   /// Data-sharing stack.
6447   DSAStackTy &Stack;
6448   /// A location for diagnostics (when there is no some better location).
6449   SourceLocation DefaultLoc;
6450   /// A location for diagnostics (when increment is not compatible).
6451   SourceLocation ConditionLoc;
6452   /// A source location for referring to loop init later.
6453   SourceRange InitSrcRange;
6454   /// A source location for referring to condition later.
6455   SourceRange ConditionSrcRange;
6456   /// A source location for referring to increment later.
6457   SourceRange IncrementSrcRange;
6458   /// Loop variable.
6459   ValueDecl *LCDecl = nullptr;
6460   /// Reference to loop variable.
6461   Expr *LCRef = nullptr;
6462   /// Lower bound (initializer for the var).
6463   Expr *LB = nullptr;
6464   /// Upper bound.
6465   Expr *UB = nullptr;
6466   /// Loop step (increment).
6467   Expr *Step = nullptr;
6468   /// This flag is true when condition is one of:
6469   ///   Var <  UB
6470   ///   Var <= UB
6471   ///   UB  >  Var
6472   ///   UB  >= Var
6473   /// This will have no value when the condition is !=
6474   llvm::Optional<bool> TestIsLessOp;
6475   /// This flag is true when condition is strict ( < or > ).
6476   bool TestIsStrictOp = false;
6477   /// This flag is true when step is subtracted on each iteration.
6478   bool SubtractStep = false;
6479   /// The outer loop counter this loop depends on (if any).
6480   const ValueDecl *DepDecl = nullptr;
6481   /// Contains number of loop (starts from 1) on which loop counter init
6482   /// expression of this loop depends on.
6483   Optional<unsigned> InitDependOnLC;
6484   /// Contains number of loop (starts from 1) on which loop counter condition
6485   /// expression of this loop depends on.
6486   Optional<unsigned> CondDependOnLC;
6487   /// Checks if the provide statement depends on the loop counter.
6488   Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6489   /// Original condition required for checking of the exit condition for
6490   /// non-rectangular loop.
6491   Expr *Condition = nullptr;
6492 
6493 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,DSAStackTy & Stack,SourceLocation DefaultLoc)6494   OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6495                               SourceLocation DefaultLoc)
6496       : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6497         ConditionLoc(DefaultLoc) {}
6498   /// Check init-expr for canonical loop form and save loop counter
6499   /// variable - #Var and its initialization value - #LB.
6500   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6501   /// Check test-expr for canonical form, save upper-bound (#UB), flags
6502   /// for less/greater and for strict/non-strict comparison.
6503   bool checkAndSetCond(Expr *S);
6504   /// Check incr-expr for canonical loop form and return true if it
6505   /// does not conform, otherwise save loop step (#Step).
6506   bool checkAndSetInc(Expr *S);
6507   /// Return the loop counter variable.
getLoopDecl() const6508   ValueDecl *getLoopDecl() const { return LCDecl; }
6509   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const6510   Expr *getLoopDeclRefExpr() const { return LCRef; }
6511   /// Source range of the loop init.
getInitSrcRange() const6512   SourceRange getInitSrcRange() const { return InitSrcRange; }
6513   /// Source range of the loop condition.
getConditionSrcRange() const6514   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6515   /// Source range of the loop increment.
getIncrementSrcRange() const6516   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6517   /// True if the step should be subtracted.
shouldSubtractStep() const6518   bool shouldSubtractStep() const { return SubtractStep; }
6519   /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const6520   bool isStrictTestOp() const { return TestIsStrictOp; }
6521   /// Build the expression to calculate the number of iterations.
6522   Expr *buildNumIterations(
6523       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6524       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6525   /// Build the precondition expression for the loops.
6526   Expr *
6527   buildPreCond(Scope *S, Expr *Cond,
6528                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6529   /// Build reference expression to the counter be used for codegen.
6530   DeclRefExpr *
6531   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6532                   DSAStackTy &DSA) const;
6533   /// Build reference expression to the private counter be used for
6534   /// codegen.
6535   Expr *buildPrivateCounterVar() const;
6536   /// Build initialization of the counter be used for codegen.
6537   Expr *buildCounterInit() const;
6538   /// Build step of the counter be used for codegen.
6539   Expr *buildCounterStep() const;
6540   /// Build loop data with counter value for depend clauses in ordered
6541   /// directives.
6542   Expr *
6543   buildOrderedLoopData(Scope *S, Expr *Counter,
6544                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6545                        SourceLocation Loc, Expr *Inc = nullptr,
6546                        OverloadedOperatorKind OOK = OO_Amp);
6547   /// Builds the minimum value for the loop counter.
6548   std::pair<Expr *, Expr *> buildMinMaxValues(
6549       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6550   /// Builds final condition for the non-rectangular loops.
6551   Expr *buildFinalCondition(Scope *S) const;
6552   /// Return true if any expression is dependent.
6553   bool dependent() const;
6554   /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const6555   bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6556   /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const6557   bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6558   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const6559   unsigned getLoopDependentIdx() const {
6560     return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6561   }
6562 
6563 private:
6564   /// Check the right-hand side of an assignment in the increment
6565   /// expression.
6566   bool checkAndSetIncRHS(Expr *RHS);
6567   /// Helper to set loop counter variable and its initializer.
6568   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6569                       bool EmitDiags);
6570   /// Helper to set upper bound.
6571   bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6572              SourceRange SR, SourceLocation SL);
6573   /// Helper to set loop increment.
6574   bool setStep(Expr *NewStep, bool Subtract);
6575 };
6576 
dependent() const6577 bool OpenMPIterationSpaceChecker::dependent() const {
6578   if (!LCDecl) {
6579     assert(!LB && !UB && !Step);
6580     return false;
6581   }
6582   return LCDecl->getType()->isDependentType() ||
6583          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6584          (Step && Step->isValueDependent());
6585 }
6586 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)6587 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6588                                                  Expr *NewLCRefExpr,
6589                                                  Expr *NewLB, bool EmitDiags) {
6590   // State consistency checking to ensure correct usage.
6591   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
6592          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6593   if (!NewLCDecl || !NewLB)
6594     return true;
6595   LCDecl = getCanonicalDecl(NewLCDecl);
6596   LCRef = NewLCRefExpr;
6597   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6598     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6599       if ((Ctor->isCopyOrMoveConstructor() ||
6600            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6601           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6602         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6603   LB = NewLB;
6604   if (EmitDiags)
6605     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6606   return false;
6607 }
6608 
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)6609 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6610                                         llvm::Optional<bool> LessOp,
6611                                         bool StrictOp, SourceRange SR,
6612                                         SourceLocation SL) {
6613   // State consistency checking to ensure correct usage.
6614   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
6615          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6616   if (!NewUB)
6617     return true;
6618   UB = NewUB;
6619   if (LessOp)
6620     TestIsLessOp = LessOp;
6621   TestIsStrictOp = StrictOp;
6622   ConditionSrcRange = SR;
6623   ConditionLoc = SL;
6624   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6625   return false;
6626 }
6627 
setStep(Expr * NewStep,bool Subtract)6628 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6629   // State consistency checking to ensure correct usage.
6630   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
6631   if (!NewStep)
6632     return true;
6633   if (!NewStep->isValueDependent()) {
6634     // Check that the step is integer expression.
6635     SourceLocation StepLoc = NewStep->getBeginLoc();
6636     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6637         StepLoc, getExprAsWritten(NewStep));
6638     if (Val.isInvalid())
6639       return true;
6640     NewStep = Val.get();
6641 
6642     // OpenMP [2.6, Canonical Loop Form, Restrictions]
6643     //  If test-expr is of form var relational-op b and relational-op is < or
6644     //  <= then incr-expr must cause var to increase on each iteration of the
6645     //  loop. If test-expr is of form var relational-op b and relational-op is
6646     //  > or >= then incr-expr must cause var to decrease on each iteration of
6647     //  the loop.
6648     //  If test-expr is of form b relational-op var and relational-op is < or
6649     //  <= then incr-expr must cause var to decrease on each iteration of the
6650     //  loop. If test-expr is of form b relational-op var and relational-op is
6651     //  > or >= then incr-expr must cause var to increase on each iteration of
6652     //  the loop.
6653     Optional<llvm::APSInt> Result =
6654         NewStep->getIntegerConstantExpr(SemaRef.Context);
6655     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6656     bool IsConstNeg =
6657         Result && Result->isSigned() && (Subtract != Result->isNegative());
6658     bool IsConstPos =
6659         Result && Result->isSigned() && (Subtract == Result->isNegative());
6660     bool IsConstZero = Result && !Result->getBoolValue();
6661 
6662     // != with increment is treated as <; != with decrement is treated as >
6663     if (!TestIsLessOp.hasValue())
6664       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6665     if (UB && (IsConstZero ||
6666                (TestIsLessOp.getValue() ?
6667                   (IsConstNeg || (IsUnsigned && Subtract)) :
6668                   (IsConstPos || (IsUnsigned && !Subtract))))) {
6669       SemaRef.Diag(NewStep->getExprLoc(),
6670                    diag::err_omp_loop_incr_not_compatible)
6671           << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6672       SemaRef.Diag(ConditionLoc,
6673                    diag::note_omp_loop_cond_requres_compatible_incr)
6674           << TestIsLessOp.getValue() << ConditionSrcRange;
6675       return true;
6676     }
6677     if (TestIsLessOp.getValue() == Subtract) {
6678       NewStep =
6679           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6680               .get();
6681       Subtract = !Subtract;
6682     }
6683   }
6684 
6685   Step = NewStep;
6686   SubtractStep = Subtract;
6687   return false;
6688 }
6689 
6690 namespace {
6691 /// Checker for the non-rectangular loops. Checks if the initializer or
6692 /// condition expression references loop counter variable.
6693 class LoopCounterRefChecker final
6694     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6695   Sema &SemaRef;
6696   DSAStackTy &Stack;
6697   const ValueDecl *CurLCDecl = nullptr;
6698   const ValueDecl *DepDecl = nullptr;
6699   const ValueDecl *PrevDepDecl = nullptr;
6700   bool IsInitializer = true;
6701   unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)6702   bool checkDecl(const Expr *E, const ValueDecl *VD) {
6703     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6704       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6705           << (IsInitializer ? 0 : 1);
6706       return false;
6707     }
6708     const auto &&Data = Stack.isLoopControlVariable(VD);
6709     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6710     // The type of the loop iterator on which we depend may not have a random
6711     // access iterator type.
6712     if (Data.first && VD->getType()->isRecordType()) {
6713       SmallString<128> Name;
6714       llvm::raw_svector_ostream OS(Name);
6715       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6716                                /*Qualified=*/true);
6717       SemaRef.Diag(E->getExprLoc(),
6718                    diag::err_omp_wrong_dependency_iterator_type)
6719           << OS.str();
6720       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6721       return false;
6722     }
6723     if (Data.first &&
6724         (DepDecl || (PrevDepDecl &&
6725                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6726       if (!DepDecl && PrevDepDecl)
6727         DepDecl = PrevDepDecl;
6728       SmallString<128> Name;
6729       llvm::raw_svector_ostream OS(Name);
6730       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6731                                     /*Qualified=*/true);
6732       SemaRef.Diag(E->getExprLoc(),
6733                    diag::err_omp_invariant_or_linear_dependency)
6734           << OS.str();
6735       return false;
6736     }
6737     if (Data.first) {
6738       DepDecl = VD;
6739       BaseLoopId = Data.first;
6740     }
6741     return Data.first;
6742   }
6743 
6744 public:
VisitDeclRefExpr(const DeclRefExpr * E)6745   bool VisitDeclRefExpr(const DeclRefExpr *E) {
6746     const ValueDecl *VD = E->getDecl();
6747     if (isa<VarDecl>(VD))
6748       return checkDecl(E, VD);
6749     return false;
6750   }
VisitMemberExpr(const MemberExpr * E)6751   bool VisitMemberExpr(const MemberExpr *E) {
6752     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6753       const ValueDecl *VD = E->getMemberDecl();
6754       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6755         return checkDecl(E, VD);
6756     }
6757     return false;
6758   }
VisitStmt(const Stmt * S)6759   bool VisitStmt(const Stmt *S) {
6760     bool Res = false;
6761     for (const Stmt *Child : S->children())
6762       Res = (Child && Visit(Child)) || Res;
6763     return Res;
6764   }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr)6765   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6766                                  const ValueDecl *CurLCDecl, bool IsInitializer,
6767                                  const ValueDecl *PrevDepDecl = nullptr)
6768       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6769         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
getBaseLoopId() const6770   unsigned getBaseLoopId() const {
6771     assert(CurLCDecl && "Expected loop dependency.");
6772     return BaseLoopId;
6773   }
getDepDecl() const6774   const ValueDecl *getDepDecl() const {
6775     assert(CurLCDecl && "Expected loop dependency.");
6776     return DepDecl;
6777   }
6778 };
6779 } // namespace
6780 
6781 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)6782 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6783                                                      bool IsInitializer) {
6784   // Check for the non-rectangular loops.
6785   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6786                                         DepDecl);
6787   if (LoopStmtChecker.Visit(S)) {
6788     DepDecl = LoopStmtChecker.getDepDecl();
6789     return LoopStmtChecker.getBaseLoopId();
6790   }
6791   return llvm::None;
6792 }
6793 
checkAndSetInit(Stmt * S,bool EmitDiags)6794 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6795   // Check init-expr for canonical loop form and save loop counter
6796   // variable - #Var and its initialization value - #LB.
6797   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6798   //   var = lb
6799   //   integer-type var = lb
6800   //   random-access-iterator-type var = lb
6801   //   pointer-type var = lb
6802   //
6803   if (!S) {
6804     if (EmitDiags) {
6805       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6806     }
6807     return true;
6808   }
6809   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6810     if (!ExprTemp->cleanupsHaveSideEffects())
6811       S = ExprTemp->getSubExpr();
6812 
6813   InitSrcRange = S->getSourceRange();
6814   if (Expr *E = dyn_cast<Expr>(S))
6815     S = E->IgnoreParens();
6816   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6817     if (BO->getOpcode() == BO_Assign) {
6818       Expr *LHS = BO->getLHS()->IgnoreParens();
6819       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6820         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6821           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6822             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6823                                   EmitDiags);
6824         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6825       }
6826       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6827         if (ME->isArrow() &&
6828             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6829           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6830                                 EmitDiags);
6831       }
6832     }
6833   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6834     if (DS->isSingleDecl()) {
6835       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6836         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6837           // Accept non-canonical init form here but emit ext. warning.
6838           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6839             SemaRef.Diag(S->getBeginLoc(),
6840                          diag::ext_omp_loop_not_canonical_init)
6841                 << S->getSourceRange();
6842           return setLCDeclAndLB(
6843               Var,
6844               buildDeclRefExpr(SemaRef, Var,
6845                                Var->getType().getNonReferenceType(),
6846                                DS->getBeginLoc()),
6847               Var->getInit(), EmitDiags);
6848         }
6849       }
6850     }
6851   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6852     if (CE->getOperator() == OO_Equal) {
6853       Expr *LHS = CE->getArg(0);
6854       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6855         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6856           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6857             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6858                                   EmitDiags);
6859         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6860       }
6861       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6862         if (ME->isArrow() &&
6863             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6864           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6865                                 EmitDiags);
6866       }
6867     }
6868   }
6869 
6870   if (dependent() || SemaRef.CurContext->isDependentContext())
6871     return false;
6872   if (EmitDiags) {
6873     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6874         << S->getSourceRange();
6875   }
6876   return true;
6877 }
6878 
6879 /// Ignore parenthesizes, implicit casts, copy constructor and return the
6880 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)6881 static const ValueDecl *getInitLCDecl(const Expr *E) {
6882   if (!E)
6883     return nullptr;
6884   E = getExprAsWritten(E);
6885   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6886     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6887       if ((Ctor->isCopyOrMoveConstructor() ||
6888            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6889           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6890         E = CE->getArg(0)->IgnoreParenImpCasts();
6891   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6892     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6893       return getCanonicalDecl(VD);
6894   }
6895   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6896     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6897       return getCanonicalDecl(ME->getMemberDecl());
6898   return nullptr;
6899 }
6900 
checkAndSetCond(Expr * S)6901 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6902   // Check test-expr for canonical form, save upper-bound UB, flags for
6903   // less/greater and for strict/non-strict comparison.
6904   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6905   //   var relational-op b
6906   //   b relational-op var
6907   //
6908   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6909   if (!S) {
6910     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6911         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6912     return true;
6913   }
6914   Condition = S;
6915   S = getExprAsWritten(S);
6916   SourceLocation CondLoc = S->getBeginLoc();
6917   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6918     if (BO->isRelationalOp()) {
6919       if (getInitLCDecl(BO->getLHS()) == LCDecl)
6920         return setUB(BO->getRHS(),
6921                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6922                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6923                      BO->getSourceRange(), BO->getOperatorLoc());
6924       if (getInitLCDecl(BO->getRHS()) == LCDecl)
6925         return setUB(BO->getLHS(),
6926                      (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6927                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6928                      BO->getSourceRange(), BO->getOperatorLoc());
6929     } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6930       return setUB(
6931           getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6932           /*LessOp=*/llvm::None,
6933           /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6934   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6935     if (CE->getNumArgs() == 2) {
6936       auto Op = CE->getOperator();
6937       switch (Op) {
6938       case OO_Greater:
6939       case OO_GreaterEqual:
6940       case OO_Less:
6941       case OO_LessEqual:
6942         if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6943           return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6944                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6945                        CE->getOperatorLoc());
6946         if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6947           return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6948                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6949                        CE->getOperatorLoc());
6950         break;
6951       case OO_ExclaimEqual:
6952         if (IneqCondIsCanonical)
6953           return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6954                                                               : CE->getArg(0),
6955                        /*LessOp=*/llvm::None,
6956                        /*StrictOp=*/true, CE->getSourceRange(),
6957                        CE->getOperatorLoc());
6958         break;
6959       default:
6960         break;
6961       }
6962     }
6963   }
6964   if (dependent() || SemaRef.CurContext->isDependentContext())
6965     return false;
6966   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6967       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6968   return true;
6969 }
6970 
checkAndSetIncRHS(Expr * RHS)6971 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6972   // RHS of canonical loop form increment can be:
6973   //   var + incr
6974   //   incr + var
6975   //   var - incr
6976   //
6977   RHS = RHS->IgnoreParenImpCasts();
6978   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6979     if (BO->isAdditiveOp()) {
6980       bool IsAdd = BO->getOpcode() == BO_Add;
6981       if (getInitLCDecl(BO->getLHS()) == LCDecl)
6982         return setStep(BO->getRHS(), !IsAdd);
6983       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6984         return setStep(BO->getLHS(), /*Subtract=*/false);
6985     }
6986   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6987     bool IsAdd = CE->getOperator() == OO_Plus;
6988     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6989       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6990         return setStep(CE->getArg(1), !IsAdd);
6991       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6992         return setStep(CE->getArg(0), /*Subtract=*/false);
6993     }
6994   }
6995   if (dependent() || SemaRef.CurContext->isDependentContext())
6996     return false;
6997   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6998       << RHS->getSourceRange() << LCDecl;
6999   return true;
7000 }
7001 
checkAndSetInc(Expr * S)7002 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7003   // Check incr-expr for canonical loop form and return true if it
7004   // does not conform.
7005   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7006   //   ++var
7007   //   var++
7008   //   --var
7009   //   var--
7010   //   var += incr
7011   //   var -= incr
7012   //   var = var + incr
7013   //   var = incr + var
7014   //   var = var - incr
7015   //
7016   if (!S) {
7017     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7018     return true;
7019   }
7020   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7021     if (!ExprTemp->cleanupsHaveSideEffects())
7022       S = ExprTemp->getSubExpr();
7023 
7024   IncrementSrcRange = S->getSourceRange();
7025   S = S->IgnoreParens();
7026   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7027     if (UO->isIncrementDecrementOp() &&
7028         getInitLCDecl(UO->getSubExpr()) == LCDecl)
7029       return setStep(SemaRef
7030                          .ActOnIntegerConstant(UO->getBeginLoc(),
7031                                                (UO->isDecrementOp() ? -1 : 1))
7032                          .get(),
7033                      /*Subtract=*/false);
7034   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7035     switch (BO->getOpcode()) {
7036     case BO_AddAssign:
7037     case BO_SubAssign:
7038       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7039         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7040       break;
7041     case BO_Assign:
7042       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7043         return checkAndSetIncRHS(BO->getRHS());
7044       break;
7045     default:
7046       break;
7047     }
7048   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7049     switch (CE->getOperator()) {
7050     case OO_PlusPlus:
7051     case OO_MinusMinus:
7052       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7053         return setStep(SemaRef
7054                            .ActOnIntegerConstant(
7055                                CE->getBeginLoc(),
7056                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7057                            .get(),
7058                        /*Subtract=*/false);
7059       break;
7060     case OO_PlusEqual:
7061     case OO_MinusEqual:
7062       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7063         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7064       break;
7065     case OO_Equal:
7066       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7067         return checkAndSetIncRHS(CE->getArg(1));
7068       break;
7069     default:
7070       break;
7071     }
7072   }
7073   if (dependent() || SemaRef.CurContext->isDependentContext())
7074     return false;
7075   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7076       << S->getSourceRange() << LCDecl;
7077   return true;
7078 }
7079 
7080 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7081 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7082                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7083   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7084     return Capture;
7085   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7086     return SemaRef.PerformImplicitConversion(
7087         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7088         /*AllowExplicit=*/true);
7089   auto I = Captures.find(Capture);
7090   if (I != Captures.end())
7091     return buildCapture(SemaRef, Capture, I->second);
7092   DeclRefExpr *Ref = nullptr;
7093   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7094   Captures[Capture] = Ref;
7095   return Res;
7096 }
7097 
7098 /// Calculate number of iterations, transforming to unsigned, if number of
7099 /// iterations may be larger than the original type.
7100 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)7101 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7102                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7103                   bool TestIsStrictOp, bool RoundToStep,
7104                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7105   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7106   if (!NewStep.isUsable())
7107     return nullptr;
7108   llvm::APSInt LRes, SRes;
7109   bool IsLowerConst = false, IsStepConst = false;
7110   if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7111     LRes = *Res;
7112     IsLowerConst = true;
7113   }
7114   if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7115     SRes = *Res;
7116     IsStepConst = true;
7117   }
7118   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7119                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
7120                           (TestIsStrictOp && LRes.isStrictlyPositive()));
7121   bool NeedToReorganize = false;
7122   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7123   if (!NoNeedToConvert && IsLowerConst &&
7124       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7125     NoNeedToConvert = true;
7126     if (RoundToStep) {
7127       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7128                         ? LRes.getBitWidth()
7129                         : SRes.getBitWidth();
7130       LRes = LRes.extend(BW + 1);
7131       LRes.setIsSigned(true);
7132       SRes = SRes.extend(BW + 1);
7133       SRes.setIsSigned(true);
7134       LRes -= SRes;
7135       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7136       LRes = LRes.trunc(BW);
7137     }
7138     if (TestIsStrictOp) {
7139       unsigned BW = LRes.getBitWidth();
7140       LRes = LRes.extend(BW + 1);
7141       LRes.setIsSigned(true);
7142       ++LRes;
7143       NoNeedToConvert =
7144           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7145       // truncate to the original bitwidth.
7146       LRes = LRes.trunc(BW);
7147     }
7148     NeedToReorganize = NoNeedToConvert;
7149   }
7150   llvm::APSInt URes;
7151   bool IsUpperConst = false;
7152   if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7153     URes = *Res;
7154     IsUpperConst = true;
7155   }
7156   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7157       (!RoundToStep || IsStepConst)) {
7158     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7159                                                           : URes.getBitWidth();
7160     LRes = LRes.extend(BW + 1);
7161     LRes.setIsSigned(true);
7162     URes = URes.extend(BW + 1);
7163     URes.setIsSigned(true);
7164     URes -= LRes;
7165     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7166     NeedToReorganize = NoNeedToConvert;
7167   }
7168   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7169   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7170   // unsigned.
7171   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7172       !LCTy->isDependentType() && LCTy->isIntegerType()) {
7173     QualType LowerTy = Lower->getType();
7174     QualType UpperTy = Upper->getType();
7175     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7176     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7177     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7178         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7179       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7180           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7181       Upper =
7182           SemaRef
7183               .PerformImplicitConversion(
7184                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7185                   CastType, Sema::AA_Converting)
7186               .get();
7187       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7188       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7189     }
7190   }
7191   if (!Lower || !Upper || NewStep.isInvalid())
7192     return nullptr;
7193 
7194   ExprResult Diff;
7195   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7196   // 1]).
7197   if (NeedToReorganize) {
7198     Diff = Lower;
7199 
7200     if (RoundToStep) {
7201       // Lower - Step
7202       Diff =
7203           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7204       if (!Diff.isUsable())
7205         return nullptr;
7206     }
7207 
7208     // Lower - Step [+ 1]
7209     if (TestIsStrictOp)
7210       Diff = SemaRef.BuildBinOp(
7211           S, DefaultLoc, BO_Add, Diff.get(),
7212           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7213     if (!Diff.isUsable())
7214       return nullptr;
7215 
7216     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7217     if (!Diff.isUsable())
7218       return nullptr;
7219 
7220     // Upper - (Lower - Step [+ 1]).
7221     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7222     if (!Diff.isUsable())
7223       return nullptr;
7224   } else {
7225     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7226 
7227     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7228       // BuildBinOp already emitted error, this one is to point user to upper
7229       // and lower bound, and to tell what is passed to 'operator-'.
7230       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7231           << Upper->getSourceRange() << Lower->getSourceRange();
7232       return nullptr;
7233     }
7234 
7235     if (!Diff.isUsable())
7236       return nullptr;
7237 
7238     // Upper - Lower [- 1]
7239     if (TestIsStrictOp)
7240       Diff = SemaRef.BuildBinOp(
7241           S, DefaultLoc, BO_Sub, Diff.get(),
7242           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7243     if (!Diff.isUsable())
7244       return nullptr;
7245 
7246     if (RoundToStep) {
7247       // Upper - Lower [- 1] + Step
7248       Diff =
7249           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7250       if (!Diff.isUsable())
7251         return nullptr;
7252     }
7253   }
7254 
7255   // Parentheses (for dumping/debugging purposes only).
7256   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7257   if (!Diff.isUsable())
7258     return nullptr;
7259 
7260   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7261   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7262   if (!Diff.isUsable())
7263     return nullptr;
7264 
7265   return Diff.get();
7266 }
7267 
7268 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7269 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7270     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7271     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7272   QualType VarType = LCDecl->getType().getNonReferenceType();
7273   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7274       !SemaRef.getLangOpts().CPlusPlus)
7275     return nullptr;
7276   Expr *LBVal = LB;
7277   Expr *UBVal = UB;
7278   // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7279   // max(LB(MinVal), LB(MaxVal))
7280   if (InitDependOnLC) {
7281     const LoopIterationSpace &IS =
7282         ResultIterSpaces[ResultIterSpaces.size() - 1 -
7283                          InitDependOnLC.getValueOr(
7284                              CondDependOnLC.getValueOr(0))];
7285     if (!IS.MinValue || !IS.MaxValue)
7286       return nullptr;
7287     // OuterVar = Min
7288     ExprResult MinValue =
7289         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7290     if (!MinValue.isUsable())
7291       return nullptr;
7292 
7293     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7294                                              IS.CounterVar, MinValue.get());
7295     if (!LBMinVal.isUsable())
7296       return nullptr;
7297     // OuterVar = Min, LBVal
7298     LBMinVal =
7299         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7300     if (!LBMinVal.isUsable())
7301       return nullptr;
7302     // (OuterVar = Min, LBVal)
7303     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7304     if (!LBMinVal.isUsable())
7305       return nullptr;
7306 
7307     // OuterVar = Max
7308     ExprResult MaxValue =
7309         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7310     if (!MaxValue.isUsable())
7311       return nullptr;
7312 
7313     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7314                                              IS.CounterVar, MaxValue.get());
7315     if (!LBMaxVal.isUsable())
7316       return nullptr;
7317     // OuterVar = Max, LBVal
7318     LBMaxVal =
7319         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7320     if (!LBMaxVal.isUsable())
7321       return nullptr;
7322     // (OuterVar = Max, LBVal)
7323     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7324     if (!LBMaxVal.isUsable())
7325       return nullptr;
7326 
7327     Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7328     Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7329     if (!LBMin || !LBMax)
7330       return nullptr;
7331     // LB(MinVal) < LB(MaxVal)
7332     ExprResult MinLessMaxRes =
7333         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7334     if (!MinLessMaxRes.isUsable())
7335       return nullptr;
7336     Expr *MinLessMax =
7337         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7338     if (!MinLessMax)
7339       return nullptr;
7340     if (TestIsLessOp.getValue()) {
7341       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7342       // LB(MaxVal))
7343       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7344                                                     MinLessMax, LBMin, LBMax);
7345       if (!MinLB.isUsable())
7346         return nullptr;
7347       LBVal = MinLB.get();
7348     } else {
7349       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7350       // LB(MaxVal))
7351       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7352                                                     MinLessMax, LBMax, LBMin);
7353       if (!MaxLB.isUsable())
7354         return nullptr;
7355       LBVal = MaxLB.get();
7356     }
7357   }
7358   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7359   // min(UB(MinVal), UB(MaxVal))
7360   if (CondDependOnLC) {
7361     const LoopIterationSpace &IS =
7362         ResultIterSpaces[ResultIterSpaces.size() - 1 -
7363                          InitDependOnLC.getValueOr(
7364                              CondDependOnLC.getValueOr(0))];
7365     if (!IS.MinValue || !IS.MaxValue)
7366       return nullptr;
7367     // OuterVar = Min
7368     ExprResult MinValue =
7369         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7370     if (!MinValue.isUsable())
7371       return nullptr;
7372 
7373     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7374                                              IS.CounterVar, MinValue.get());
7375     if (!UBMinVal.isUsable())
7376       return nullptr;
7377     // OuterVar = Min, UBVal
7378     UBMinVal =
7379         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7380     if (!UBMinVal.isUsable())
7381       return nullptr;
7382     // (OuterVar = Min, UBVal)
7383     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7384     if (!UBMinVal.isUsable())
7385       return nullptr;
7386 
7387     // OuterVar = Max
7388     ExprResult MaxValue =
7389         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7390     if (!MaxValue.isUsable())
7391       return nullptr;
7392 
7393     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7394                                              IS.CounterVar, MaxValue.get());
7395     if (!UBMaxVal.isUsable())
7396       return nullptr;
7397     // OuterVar = Max, UBVal
7398     UBMaxVal =
7399         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7400     if (!UBMaxVal.isUsable())
7401       return nullptr;
7402     // (OuterVar = Max, UBVal)
7403     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7404     if (!UBMaxVal.isUsable())
7405       return nullptr;
7406 
7407     Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7408     Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7409     if (!UBMin || !UBMax)
7410       return nullptr;
7411     // UB(MinVal) > UB(MaxVal)
7412     ExprResult MinGreaterMaxRes =
7413         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7414     if (!MinGreaterMaxRes.isUsable())
7415       return nullptr;
7416     Expr *MinGreaterMax =
7417         tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7418     if (!MinGreaterMax)
7419       return nullptr;
7420     if (TestIsLessOp.getValue()) {
7421       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7422       // UB(MaxVal))
7423       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7424           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7425       if (!MaxUB.isUsable())
7426         return nullptr;
7427       UBVal = MaxUB.get();
7428     } else {
7429       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7430       // UB(MaxVal))
7431       ExprResult MinUB = SemaRef.ActOnConditionalOp(
7432           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7433       if (!MinUB.isUsable())
7434         return nullptr;
7435       UBVal = MinUB.get();
7436     }
7437   }
7438   Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7439   Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7440   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7441   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7442   if (!Upper || !Lower)
7443     return nullptr;
7444 
7445   ExprResult Diff =
7446       calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7447                         TestIsStrictOp, /*RoundToStep=*/true, Captures);
7448   if (!Diff.isUsable())
7449     return nullptr;
7450 
7451   // OpenMP runtime requires 32-bit or 64-bit loop variables.
7452   QualType Type = Diff.get()->getType();
7453   ASTContext &C = SemaRef.Context;
7454   bool UseVarType = VarType->hasIntegerRepresentation() &&
7455                     C.getTypeSize(Type) > C.getTypeSize(VarType);
7456   if (!Type->isIntegerType() || UseVarType) {
7457     unsigned NewSize =
7458         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7459     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7460                                : Type->hasSignedIntegerRepresentation();
7461     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7462     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7463       Diff = SemaRef.PerformImplicitConversion(
7464           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7465       if (!Diff.isUsable())
7466         return nullptr;
7467     }
7468   }
7469   if (LimitedType) {
7470     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7471     if (NewSize != C.getTypeSize(Type)) {
7472       if (NewSize < C.getTypeSize(Type)) {
7473         assert(NewSize == 64 && "incorrect loop var size");
7474         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7475             << InitSrcRange << ConditionSrcRange;
7476       }
7477       QualType NewType = C.getIntTypeForBitwidth(
7478           NewSize, Type->hasSignedIntegerRepresentation() ||
7479                        C.getTypeSize(Type) < NewSize);
7480       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7481         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7482                                                  Sema::AA_Converting, true);
7483         if (!Diff.isUsable())
7484           return nullptr;
7485       }
7486     }
7487   }
7488 
7489   return Diff.get();
7490 }
7491 
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7492 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7493     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7494   // Do not build for iterators, they cannot be used in non-rectangular loop
7495   // nests.
7496   if (LCDecl->getType()->isRecordType())
7497     return std::make_pair(nullptr, nullptr);
7498   // If we subtract, the min is in the condition, otherwise the min is in the
7499   // init value.
7500   Expr *MinExpr = nullptr;
7501   Expr *MaxExpr = nullptr;
7502   Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7503   Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7504   bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7505                                            : CondDependOnLC.hasValue();
7506   bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7507                                            : InitDependOnLC.hasValue();
7508   Expr *Lower =
7509       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7510   Expr *Upper =
7511       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7512   if (!Upper || !Lower)
7513     return std::make_pair(nullptr, nullptr);
7514 
7515   if (TestIsLessOp.getValue())
7516     MinExpr = Lower;
7517   else
7518     MaxExpr = Upper;
7519 
7520   // Build minimum/maximum value based on number of iterations.
7521   QualType VarType = LCDecl->getType().getNonReferenceType();
7522 
7523   ExprResult Diff =
7524       calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7525                         TestIsStrictOp, /*RoundToStep=*/false, Captures);
7526   if (!Diff.isUsable())
7527     return std::make_pair(nullptr, nullptr);
7528 
7529   // ((Upper - Lower [- 1]) / Step) * Step
7530   // Parentheses (for dumping/debugging purposes only).
7531   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7532   if (!Diff.isUsable())
7533     return std::make_pair(nullptr, nullptr);
7534 
7535   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7536   if (!NewStep.isUsable())
7537     return std::make_pair(nullptr, nullptr);
7538   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7539   if (!Diff.isUsable())
7540     return std::make_pair(nullptr, nullptr);
7541 
7542   // Parentheses (for dumping/debugging purposes only).
7543   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7544   if (!Diff.isUsable())
7545     return std::make_pair(nullptr, nullptr);
7546 
7547   // Convert to the ptrdiff_t, if original type is pointer.
7548   if (VarType->isAnyPointerType() &&
7549       !SemaRef.Context.hasSameType(
7550           Diff.get()->getType(),
7551           SemaRef.Context.getUnsignedPointerDiffType())) {
7552     Diff = SemaRef.PerformImplicitConversion(
7553         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7554         Sema::AA_Converting, /*AllowExplicit=*/true);
7555   }
7556   if (!Diff.isUsable())
7557     return std::make_pair(nullptr, nullptr);
7558 
7559   if (TestIsLessOp.getValue()) {
7560     // MinExpr = Lower;
7561     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7562     Diff = SemaRef.BuildBinOp(
7563         S, DefaultLoc, BO_Add,
7564         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7565         Diff.get());
7566     if (!Diff.isUsable())
7567       return std::make_pair(nullptr, nullptr);
7568   } else {
7569     // MaxExpr = Upper;
7570     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7571     Diff = SemaRef.BuildBinOp(
7572         S, DefaultLoc, BO_Sub,
7573         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7574         Diff.get());
7575     if (!Diff.isUsable())
7576       return std::make_pair(nullptr, nullptr);
7577   }
7578 
7579   // Convert to the original type.
7580   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7581     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7582                                              Sema::AA_Converting,
7583                                              /*AllowExplicit=*/true);
7584   if (!Diff.isUsable())
7585     return std::make_pair(nullptr, nullptr);
7586 
7587   Sema::TentativeAnalysisScope Trap(SemaRef);
7588   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7589   if (!Diff.isUsable())
7590     return std::make_pair(nullptr, nullptr);
7591 
7592   if (TestIsLessOp.getValue())
7593     MaxExpr = Diff.get();
7594   else
7595     MinExpr = Diff.get();
7596 
7597   return std::make_pair(MinExpr, MaxExpr);
7598 }
7599 
buildFinalCondition(Scope * S) const7600 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7601   if (InitDependOnLC || CondDependOnLC)
7602     return Condition;
7603   return nullptr;
7604 }
7605 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const7606 Expr *OpenMPIterationSpaceChecker::buildPreCond(
7607     Scope *S, Expr *Cond,
7608     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7609   // Do not build a precondition when the condition/initialization is dependent
7610   // to prevent pessimistic early loop exit.
7611   // TODO: this can be improved by calculating min/max values but not sure that
7612   // it will be very effective.
7613   if (CondDependOnLC || InitDependOnLC)
7614     return SemaRef.PerformImplicitConversion(
7615         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7616         SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7617         /*AllowExplicit=*/true).get();
7618 
7619   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7620   Sema::TentativeAnalysisScope Trap(SemaRef);
7621 
7622   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7623   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7624   if (!NewLB.isUsable() || !NewUB.isUsable())
7625     return nullptr;
7626 
7627   ExprResult CondExpr =
7628       SemaRef.BuildBinOp(S, DefaultLoc,
7629                          TestIsLessOp.getValue() ?
7630                            (TestIsStrictOp ? BO_LT : BO_LE) :
7631                            (TestIsStrictOp ? BO_GT : BO_GE),
7632                          NewLB.get(), NewUB.get());
7633   if (CondExpr.isUsable()) {
7634     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7635                                                 SemaRef.Context.BoolTy))
7636       CondExpr = SemaRef.PerformImplicitConversion(
7637           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7638           /*AllowExplicit=*/true);
7639   }
7640 
7641   // Otherwise use original loop condition and evaluate it in runtime.
7642   return CondExpr.isUsable() ? CondExpr.get() : Cond;
7643 }
7644 
7645 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const7646 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7647     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7648     DSAStackTy &DSA) const {
7649   auto *VD = dyn_cast<VarDecl>(LCDecl);
7650   if (!VD) {
7651     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7652     DeclRefExpr *Ref = buildDeclRefExpr(
7653         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7654     const DSAStackTy::DSAVarData Data =
7655         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7656     // If the loop control decl is explicitly marked as private, do not mark it
7657     // as captured again.
7658     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7659       Captures.insert(std::make_pair(LCRef, Ref));
7660     return Ref;
7661   }
7662   return cast<DeclRefExpr>(LCRef);
7663 }
7664 
buildPrivateCounterVar() const7665 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7666   if (LCDecl && !LCDecl->isInvalidDecl()) {
7667     QualType Type = LCDecl->getType().getNonReferenceType();
7668     VarDecl *PrivateVar = buildVarDecl(
7669         SemaRef, DefaultLoc, Type, LCDecl->getName(),
7670         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7671         isa<VarDecl>(LCDecl)
7672             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7673             : nullptr);
7674     if (PrivateVar->isInvalidDecl())
7675       return nullptr;
7676     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7677   }
7678   return nullptr;
7679 }
7680 
7681 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const7682 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7683 
7684 /// Build step of the counter be used for codegen.
buildCounterStep() const7685 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7686 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)7687 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7688     Scope *S, Expr *Counter,
7689     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7690     Expr *Inc, OverloadedOperatorKind OOK) {
7691   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7692   if (!Cnt)
7693     return nullptr;
7694   if (Inc) {
7695     assert((OOK == OO_Plus || OOK == OO_Minus) &&
7696            "Expected only + or - operations for depend clauses.");
7697     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7698     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7699     if (!Cnt)
7700       return nullptr;
7701   }
7702   QualType VarType = LCDecl->getType().getNonReferenceType();
7703   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7704       !SemaRef.getLangOpts().CPlusPlus)
7705     return nullptr;
7706   // Upper - Lower
7707   Expr *Upper = TestIsLessOp.getValue()
7708                     ? Cnt
7709                     : tryBuildCapture(SemaRef, LB, Captures).get();
7710   Expr *Lower = TestIsLessOp.getValue()
7711                     ? tryBuildCapture(SemaRef, LB, Captures).get()
7712                     : Cnt;
7713   if (!Upper || !Lower)
7714     return nullptr;
7715 
7716   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7717                                       Step, VarType, /*TestIsStrictOp=*/false,
7718                                       /*RoundToStep=*/false, Captures);
7719   if (!Diff.isUsable())
7720     return nullptr;
7721 
7722   return Diff.get();
7723 }
7724 } // namespace
7725 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)7726 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7727   assert(getLangOpts().OpenMP && "OpenMP is not active.");
7728   assert(Init && "Expected loop in canonical form.");
7729   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
7730   if (AssociatedLoops > 0 &&
7731       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
7732     DSAStack->loopStart();
7733     OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
7734     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7735       if (ValueDecl *D = ISC.getLoopDecl()) {
7736         auto *VD = dyn_cast<VarDecl>(D);
7737         DeclRefExpr *PrivateRef = nullptr;
7738         if (!VD) {
7739           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7740             VD = Private;
7741           } else {
7742             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7743                                       /*WithInit=*/false);
7744             VD = cast<VarDecl>(PrivateRef->getDecl());
7745           }
7746         }
7747         DSAStack->addLoopControlVariable(D, VD);
7748         const Decl *LD = DSAStack->getPossiblyLoopCunter();
7749         if (LD != D->getCanonicalDecl()) {
7750           DSAStack->resetPossibleLoopCounter();
7751           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7752             MarkDeclarationsReferencedInExpr(
7753                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7754                                  Var->getType().getNonLValueExprType(Context),
7755                                  ForLoc, /*RefersToCapture=*/true));
7756         }
7757         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
7758         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7759         // Referenced in a Construct, C/C++]. The loop iteration variable in the
7760         // associated for-loop of a simd construct with just one associated
7761         // for-loop may be listed in a linear clause with a constant-linear-step
7762         // that is the increment of the associated for-loop. The loop iteration
7763         // variable(s) in the associated for-loop(s) of a for or parallel for
7764         // construct may be listed in a private or lastprivate clause.
7765         DSAStackTy::DSAVarData DVar =
7766             DSAStack->getTopDSA(D, /*FromParent=*/false);
7767         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7768         // is declared in the loop and it is predetermined as a private.
7769         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7770         OpenMPClauseKind PredeterminedCKind =
7771             isOpenMPSimdDirective(DKind)
7772                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7773                 : OMPC_private;
7774         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7775               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7776               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7777                                          DVar.CKind != OMPC_private))) ||
7778              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7779                DKind == OMPD_master_taskloop ||
7780                DKind == OMPD_parallel_master_taskloop ||
7781                isOpenMPDistributeDirective(DKind)) &&
7782               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7783               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7784             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7785           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7786               << getOpenMPClauseName(DVar.CKind)
7787               << getOpenMPDirectiveName(DKind)
7788               << getOpenMPClauseName(PredeterminedCKind);
7789           if (DVar.RefExpr == nullptr)
7790             DVar.CKind = PredeterminedCKind;
7791           reportOriginalDsa(*this, DSAStack, D, DVar,
7792                             /*IsLoopIterVar=*/true);
7793         } else if (LoopDeclRefExpr) {
7794           // Make the loop iteration variable private (for worksharing
7795           // constructs), linear (for simd directives with the only one
7796           // associated loop) or lastprivate (for simd directives with several
7797           // collapsed or ordered loops).
7798           if (DVar.CKind == OMPC_unknown)
7799             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7800                              PrivateRef);
7801         }
7802       }
7803     }
7804     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
7805   }
7806 }
7807 
7808 /// Called on a for stmt to check and extract its iteration space
7809 /// 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)7810 static bool checkOpenMPIterationSpace(
7811     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7812     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7813     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7814     Expr *OrderedLoopCountExpr,
7815     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7816     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7817     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7818   // OpenMP [2.9.1, Canonical Loop Form]
7819   //   for (init-expr; test-expr; incr-expr) structured-block
7820   //   for (range-decl: range-expr) structured-block
7821   auto *For = dyn_cast_or_null<ForStmt>(S);
7822   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7823   // Ranged for is supported only in OpenMP 5.0.
7824   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7825     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7826         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7827         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7828         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7829     if (TotalNestedLoopCount > 1) {
7830       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7831         SemaRef.Diag(DSA.getConstructLoc(),
7832                      diag::note_omp_collapse_ordered_expr)
7833             << 2 << CollapseLoopCountExpr->getSourceRange()
7834             << OrderedLoopCountExpr->getSourceRange();
7835       else if (CollapseLoopCountExpr)
7836         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7837                      diag::note_omp_collapse_ordered_expr)
7838             << 0 << CollapseLoopCountExpr->getSourceRange();
7839       else
7840         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7841                      diag::note_omp_collapse_ordered_expr)
7842             << 1 << OrderedLoopCountExpr->getSourceRange();
7843     }
7844     return true;
7845   }
7846   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
7847          "No loop body.");
7848 
7849   OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7850                                   For ? For->getForLoc() : CXXFor->getForLoc());
7851 
7852   // Check init.
7853   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7854   if (ISC.checkAndSetInit(Init))
7855     return true;
7856 
7857   bool HasErrors = false;
7858 
7859   // Check loop variable's type.
7860   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7861     // OpenMP [2.6, Canonical Loop Form]
7862     // Var is one of the following:
7863     //   A variable of signed or unsigned integer type.
7864     //   For C++, a variable of a random access iterator type.
7865     //   For C, a variable of a pointer type.
7866     QualType VarType = LCDecl->getType().getNonReferenceType();
7867     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7868         !VarType->isPointerType() &&
7869         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7870       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7871           << SemaRef.getLangOpts().CPlusPlus;
7872       HasErrors = true;
7873     }
7874 
7875     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7876     // a Construct
7877     // The loop iteration variable(s) in the associated for-loop(s) of a for or
7878     // parallel for construct is (are) private.
7879     // The loop iteration variable in the associated for-loop of a simd
7880     // construct with just one associated for-loop is linear with a
7881     // constant-linear-step that is the increment of the associated for-loop.
7882     // Exclude loop var from the list of variables with implicitly defined data
7883     // sharing attributes.
7884     VarsWithImplicitDSA.erase(LCDecl);
7885 
7886     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
7887 
7888     // Check test-expr.
7889     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7890 
7891     // Check incr-expr.
7892     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7893   }
7894 
7895   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7896     return HasErrors;
7897 
7898   // Build the loop's iteration space representation.
7899   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7900       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7901   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7902       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7903                              (isOpenMPWorksharingDirective(DKind) ||
7904                               isOpenMPTaskLoopDirective(DKind) ||
7905                               isOpenMPDistributeDirective(DKind)),
7906                              Captures);
7907   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7908       ISC.buildCounterVar(Captures, DSA);
7909   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7910       ISC.buildPrivateCounterVar();
7911   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7912   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7913   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7914   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7915       ISC.getConditionSrcRange();
7916   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7917       ISC.getIncrementSrcRange();
7918   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7919   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7920       ISC.isStrictTestOp();
7921   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7922            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7923       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7924   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7925       ISC.buildFinalCondition(DSA.getCurScope());
7926   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7927       ISC.doesInitDependOnLC();
7928   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7929       ISC.doesCondDependOnLC();
7930   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7931       ISC.getLoopDependentIdx();
7932 
7933   HasErrors |=
7934       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7935        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7936        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7937        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7938        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7939        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7940   if (!HasErrors && DSA.isOrderedRegion()) {
7941     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7942       if (CurrentNestedLoopCount <
7943           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7944         DSA.getOrderedRegionParam().second->setLoopNumIterations(
7945             CurrentNestedLoopCount,
7946             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7947         DSA.getOrderedRegionParam().second->setLoopCounter(
7948             CurrentNestedLoopCount,
7949             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7950       }
7951     }
7952     for (auto &Pair : DSA.getDoacrossDependClauses()) {
7953       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7954         // Erroneous case - clause has some problems.
7955         continue;
7956       }
7957       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7958           Pair.second.size() <= CurrentNestedLoopCount) {
7959         // Erroneous case - clause has some problems.
7960         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7961         continue;
7962       }
7963       Expr *CntValue;
7964       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7965         CntValue = ISC.buildOrderedLoopData(
7966             DSA.getCurScope(),
7967             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7968             Pair.first->getDependencyLoc());
7969       else
7970         CntValue = ISC.buildOrderedLoopData(
7971             DSA.getCurScope(),
7972             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7973             Pair.first->getDependencyLoc(),
7974             Pair.second[CurrentNestedLoopCount].first,
7975             Pair.second[CurrentNestedLoopCount].second);
7976       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7977     }
7978   }
7979 
7980   return HasErrors;
7981 }
7982 
7983 /// Build 'VarRef = Start.
7984 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7985 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7986                  ExprResult Start, bool IsNonRectangularLB,
7987                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7988   // Build 'VarRef = Start.
7989   ExprResult NewStart = IsNonRectangularLB
7990                             ? Start.get()
7991                             : tryBuildCapture(SemaRef, Start.get(), Captures);
7992   if (!NewStart.isUsable())
7993     return ExprError();
7994   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7995                                    VarRef.get()->getType())) {
7996     NewStart = SemaRef.PerformImplicitConversion(
7997         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7998         /*AllowExplicit=*/true);
7999     if (!NewStart.isUsable())
8000       return ExprError();
8001   }
8002 
8003   ExprResult Init =
8004       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8005   return Init;
8006 }
8007 
8008 /// 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)8009 static ExprResult buildCounterUpdate(
8010     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8011     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8012     bool IsNonRectangularLB,
8013     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8014   // Add parentheses (for debugging purposes only).
8015   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8016   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8017       !Step.isUsable())
8018     return ExprError();
8019 
8020   ExprResult NewStep = Step;
8021   if (Captures)
8022     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8023   if (NewStep.isInvalid())
8024     return ExprError();
8025   ExprResult Update =
8026       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8027   if (!Update.isUsable())
8028     return ExprError();
8029 
8030   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8031   // 'VarRef = Start (+|-) Iter * Step'.
8032   if (!Start.isUsable())
8033     return ExprError();
8034   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8035   if (!NewStart.isUsable())
8036     return ExprError();
8037   if (Captures && !IsNonRectangularLB)
8038     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8039   if (NewStart.isInvalid())
8040     return ExprError();
8041 
8042   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8043   ExprResult SavedUpdate = Update;
8044   ExprResult UpdateVal;
8045   if (VarRef.get()->getType()->isOverloadableType() ||
8046       NewStart.get()->getType()->isOverloadableType() ||
8047       Update.get()->getType()->isOverloadableType()) {
8048     Sema::TentativeAnalysisScope Trap(SemaRef);
8049 
8050     Update =
8051         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8052     if (Update.isUsable()) {
8053       UpdateVal =
8054           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8055                              VarRef.get(), SavedUpdate.get());
8056       if (UpdateVal.isUsable()) {
8057         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8058                                             UpdateVal.get());
8059       }
8060     }
8061   }
8062 
8063   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8064   if (!Update.isUsable() || !UpdateVal.isUsable()) {
8065     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8066                                 NewStart.get(), SavedUpdate.get());
8067     if (!Update.isUsable())
8068       return ExprError();
8069 
8070     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8071                                      VarRef.get()->getType())) {
8072       Update = SemaRef.PerformImplicitConversion(
8073           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8074       if (!Update.isUsable())
8075         return ExprError();
8076     }
8077 
8078     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8079   }
8080   return Update;
8081 }
8082 
8083 /// Convert integer expression \a E to make it have at least \a Bits
8084 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8085 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8086   if (E == nullptr)
8087     return ExprError();
8088   ASTContext &C = SemaRef.Context;
8089   QualType OldType = E->getType();
8090   unsigned HasBits = C.getTypeSize(OldType);
8091   if (HasBits >= Bits)
8092     return ExprResult(E);
8093   // OK to convert to signed, because new type has more bits than old.
8094   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8095   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8096                                            true);
8097 }
8098 
8099 /// Check if the given expression \a E is a constant integer that fits
8100 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8101 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8102   if (E == nullptr)
8103     return false;
8104   if (Optional<llvm::APSInt> Result =
8105           E->getIntegerConstantExpr(SemaRef.Context))
8106     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8107   return false;
8108 }
8109 
8110 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8111 static Stmt *buildPreInits(ASTContext &Context,
8112                            MutableArrayRef<Decl *> PreInits) {
8113   if (!PreInits.empty()) {
8114     return new (Context) DeclStmt(
8115         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8116         SourceLocation(), SourceLocation());
8117   }
8118   return nullptr;
8119 }
8120 
8121 /// Build preinits statement for the given declarations.
8122 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8123 buildPreInits(ASTContext &Context,
8124               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8125   if (!Captures.empty()) {
8126     SmallVector<Decl *, 16> PreInits;
8127     for (const auto &Pair : Captures)
8128       PreInits.push_back(Pair.second->getDecl());
8129     return buildPreInits(Context, PreInits);
8130   }
8131   return nullptr;
8132 }
8133 
8134 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8135 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8136   Expr *PostUpdate = nullptr;
8137   if (!PostUpdates.empty()) {
8138     for (Expr *E : PostUpdates) {
8139       Expr *ConvE = S.BuildCStyleCastExpr(
8140                          E->getExprLoc(),
8141                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8142                          E->getExprLoc(), E)
8143                         .get();
8144       PostUpdate = PostUpdate
8145                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8146                                               PostUpdate, ConvE)
8147                              .get()
8148                        : ConvE;
8149     }
8150   }
8151   return PostUpdate;
8152 }
8153 
8154 /// Called on a for stmt to check itself and nested loops (if any).
8155 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8156 /// number of collapsed loops otherwise.
8157 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopDirective::HelperExprs & Built)8158 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8159                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8160                 DSAStackTy &DSA,
8161                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8162                 OMPLoopDirective::HelperExprs &Built) {
8163   unsigned NestedLoopCount = 1;
8164   if (CollapseLoopCountExpr) {
8165     // Found 'collapse' clause - calculate collapse number.
8166     Expr::EvalResult Result;
8167     if (!CollapseLoopCountExpr->isValueDependent() &&
8168         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8169       NestedLoopCount = Result.Val.getInt().getLimitedValue();
8170     } else {
8171       Built.clear(/*Size=*/1);
8172       return 1;
8173     }
8174   }
8175   unsigned OrderedLoopCount = 1;
8176   if (OrderedLoopCountExpr) {
8177     // Found 'ordered' clause - calculate collapse number.
8178     Expr::EvalResult EVResult;
8179     if (!OrderedLoopCountExpr->isValueDependent() &&
8180         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8181                                             SemaRef.getASTContext())) {
8182       llvm::APSInt Result = EVResult.Val.getInt();
8183       if (Result.getLimitedValue() < NestedLoopCount) {
8184         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8185                      diag::err_omp_wrong_ordered_loop_count)
8186             << OrderedLoopCountExpr->getSourceRange();
8187         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8188                      diag::note_collapse_loop_count)
8189             << CollapseLoopCountExpr->getSourceRange();
8190       }
8191       OrderedLoopCount = Result.getLimitedValue();
8192     } else {
8193       Built.clear(/*Size=*/1);
8194       return 1;
8195     }
8196   }
8197   // This is helper routine for loop directives (e.g., 'for', 'simd',
8198   // 'for simd', etc.).
8199   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8200   SmallVector<LoopIterationSpace, 4> IterSpaces(
8201       std::max(OrderedLoopCount, NestedLoopCount));
8202   Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8203   for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8204     if (checkOpenMPIterationSpace(
8205             DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8206             std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8207             OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8208       return 0;
8209     // Move on to the next nested for loop, or to the loop body.
8210     // OpenMP [2.8.1, simd construct, Restrictions]
8211     // All loops associated with the construct must be perfectly nested; that
8212     // is, there must be no intervening code nor any OpenMP directive between
8213     // any two loops.
8214     if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8215       CurStmt = For->getBody();
8216     } else {
8217       assert(isa<CXXForRangeStmt>(CurStmt) &&
8218              "Expected canonical for or range-based for loops.");
8219       CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8220     }
8221     CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8222         CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8223   }
8224   for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8225     if (checkOpenMPIterationSpace(
8226             DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8227             std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8228             OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8229       return 0;
8230     if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8231       // Handle initialization of captured loop iterator variables.
8232       auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8233       if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8234         Captures[DRE] = DRE;
8235       }
8236     }
8237     // Move on to the next nested for loop, or to the loop body.
8238     // OpenMP [2.8.1, simd construct, Restrictions]
8239     // All loops associated with the construct must be perfectly nested; that
8240     // is, there must be no intervening code nor any OpenMP directive between
8241     // any two loops.
8242     if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8243       CurStmt = For->getBody();
8244     } else {
8245       assert(isa<CXXForRangeStmt>(CurStmt) &&
8246              "Expected canonical for or range-based for loops.");
8247       CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8248     }
8249     CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8250         CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8251   }
8252 
8253   Built.clear(/* size */ NestedLoopCount);
8254 
8255   if (SemaRef.CurContext->isDependentContext())
8256     return NestedLoopCount;
8257 
8258   // An example of what is generated for the following code:
8259   //
8260   //   #pragma omp simd collapse(2) ordered(2)
8261   //   for (i = 0; i < NI; ++i)
8262   //     for (k = 0; k < NK; ++k)
8263   //       for (j = J0; j < NJ; j+=2) {
8264   //         <loop body>
8265   //       }
8266   //
8267   // We generate the code below.
8268   // Note: the loop body may be outlined in CodeGen.
8269   // Note: some counters may be C++ classes, operator- is used to find number of
8270   // iterations and operator+= to calculate counter value.
8271   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8272   // or i64 is currently supported).
8273   //
8274   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8275   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8276   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8277   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8278   //     // similar updates for vars in clauses (e.g. 'linear')
8279   //     <loop body (using local i and j)>
8280   //   }
8281   //   i = NI; // assign final values of counters
8282   //   j = NJ;
8283   //
8284 
8285   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8286   // the iteration counts of the collapsed for loops.
8287   // Precondition tests if there is at least one iteration (all conditions are
8288   // true).
8289   auto PreCond = ExprResult(IterSpaces[0].PreCond);
8290   Expr *N0 = IterSpaces[0].NumIterations;
8291   ExprResult LastIteration32 =
8292       widenIterationCount(/*Bits=*/32,
8293                           SemaRef
8294                               .PerformImplicitConversion(
8295                                   N0->IgnoreImpCasts(), N0->getType(),
8296                                   Sema::AA_Converting, /*AllowExplicit=*/true)
8297                               .get(),
8298                           SemaRef);
8299   ExprResult LastIteration64 = widenIterationCount(
8300       /*Bits=*/64,
8301       SemaRef
8302           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8303                                      Sema::AA_Converting,
8304                                      /*AllowExplicit=*/true)
8305           .get(),
8306       SemaRef);
8307 
8308   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8309     return NestedLoopCount;
8310 
8311   ASTContext &C = SemaRef.Context;
8312   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8313 
8314   Scope *CurScope = DSA.getCurScope();
8315   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8316     if (PreCond.isUsable()) {
8317       PreCond =
8318           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8319                              PreCond.get(), IterSpaces[Cnt].PreCond);
8320     }
8321     Expr *N = IterSpaces[Cnt].NumIterations;
8322     SourceLocation Loc = N->getExprLoc();
8323     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8324     if (LastIteration32.isUsable())
8325       LastIteration32 = SemaRef.BuildBinOp(
8326           CurScope, Loc, BO_Mul, LastIteration32.get(),
8327           SemaRef
8328               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8329                                          Sema::AA_Converting,
8330                                          /*AllowExplicit=*/true)
8331               .get());
8332     if (LastIteration64.isUsable())
8333       LastIteration64 = SemaRef.BuildBinOp(
8334           CurScope, Loc, BO_Mul, LastIteration64.get(),
8335           SemaRef
8336               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8337                                          Sema::AA_Converting,
8338                                          /*AllowExplicit=*/true)
8339               .get());
8340   }
8341 
8342   // Choose either the 32-bit or 64-bit version.
8343   ExprResult LastIteration = LastIteration64;
8344   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8345       (LastIteration32.isUsable() &&
8346        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8347        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8348         fitsInto(
8349             /*Bits=*/32,
8350             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8351             LastIteration64.get(), SemaRef))))
8352     LastIteration = LastIteration32;
8353   QualType VType = LastIteration.get()->getType();
8354   QualType RealVType = VType;
8355   QualType StrideVType = VType;
8356   if (isOpenMPTaskLoopDirective(DKind)) {
8357     VType =
8358         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8359     StrideVType =
8360         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8361   }
8362 
8363   if (!LastIteration.isUsable())
8364     return 0;
8365 
8366   // Save the number of iterations.
8367   ExprResult NumIterations = LastIteration;
8368   {
8369     LastIteration = SemaRef.BuildBinOp(
8370         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8371         LastIteration.get(),
8372         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8373     if (!LastIteration.isUsable())
8374       return 0;
8375   }
8376 
8377   // Calculate the last iteration number beforehand instead of doing this on
8378   // each iteration. Do not do this if the number of iterations may be kfold-ed.
8379   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8380   ExprResult CalcLastIteration;
8381   if (!IsConstant) {
8382     ExprResult SaveRef =
8383         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8384     LastIteration = SaveRef;
8385 
8386     // Prepare SaveRef + 1.
8387     NumIterations = SemaRef.BuildBinOp(
8388         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8389         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8390     if (!NumIterations.isUsable())
8391       return 0;
8392   }
8393 
8394   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8395 
8396   // Build variables passed into runtime, necessary for worksharing directives.
8397   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8398   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8399       isOpenMPDistributeDirective(DKind)) {
8400     // Lower bound variable, initialized with zero.
8401     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8402     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8403     SemaRef.AddInitializerToDecl(LBDecl,
8404                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8405                                  /*DirectInit*/ false);
8406 
8407     // Upper bound variable, initialized with last iteration number.
8408     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8409     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8410     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8411                                  /*DirectInit*/ false);
8412 
8413     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8414     // This will be used to implement clause 'lastprivate'.
8415     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8416     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8417     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8418     SemaRef.AddInitializerToDecl(ILDecl,
8419                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8420                                  /*DirectInit*/ false);
8421 
8422     // Stride variable returned by runtime (we initialize it to 1 by default).
8423     VarDecl *STDecl =
8424         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8425     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8426     SemaRef.AddInitializerToDecl(STDecl,
8427                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8428                                  /*DirectInit*/ false);
8429 
8430     // Build expression: UB = min(UB, LastIteration)
8431     // It is necessary for CodeGen of directives with static scheduling.
8432     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8433                                                 UB.get(), LastIteration.get());
8434     ExprResult CondOp = SemaRef.ActOnConditionalOp(
8435         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8436         LastIteration.get(), UB.get());
8437     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8438                              CondOp.get());
8439     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8440 
8441     // If we have a combined directive that combines 'distribute', 'for' or
8442     // 'simd' we need to be able to access the bounds of the schedule of the
8443     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8444     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8445     if (isOpenMPLoopBoundSharingDirective(DKind)) {
8446       // Lower bound variable, initialized with zero.
8447       VarDecl *CombLBDecl =
8448           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8449       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8450       SemaRef.AddInitializerToDecl(
8451           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8452           /*DirectInit*/ false);
8453 
8454       // Upper bound variable, initialized with last iteration number.
8455       VarDecl *CombUBDecl =
8456           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8457       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8458       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8459                                    /*DirectInit*/ false);
8460 
8461       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8462           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8463       ExprResult CombCondOp =
8464           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8465                                      LastIteration.get(), CombUB.get());
8466       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8467                                    CombCondOp.get());
8468       CombEUB =
8469           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8470 
8471       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8472       // We expect to have at least 2 more parameters than the 'parallel'
8473       // directive does - the lower and upper bounds of the previous schedule.
8474       assert(CD->getNumParams() >= 4 &&
8475              "Unexpected number of parameters in loop combined directive");
8476 
8477       // Set the proper type for the bounds given what we learned from the
8478       // enclosed loops.
8479       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8480       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8481 
8482       // Previous lower and upper bounds are obtained from the region
8483       // parameters.
8484       PrevLB =
8485           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8486       PrevUB =
8487           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8488     }
8489   }
8490 
8491   // Build the iteration variable and its initialization before loop.
8492   ExprResult IV;
8493   ExprResult Init, CombInit;
8494   {
8495     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8496     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8497     Expr *RHS =
8498         (isOpenMPWorksharingDirective(DKind) ||
8499          isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8500             ? LB.get()
8501             : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8502     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8503     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8504 
8505     if (isOpenMPLoopBoundSharingDirective(DKind)) {
8506       Expr *CombRHS =
8507           (isOpenMPWorksharingDirective(DKind) ||
8508            isOpenMPTaskLoopDirective(DKind) ||
8509            isOpenMPDistributeDirective(DKind))
8510               ? CombLB.get()
8511               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8512       CombInit =
8513           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8514       CombInit =
8515           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8516     }
8517   }
8518 
8519   bool UseStrictCompare =
8520       RealVType->hasUnsignedIntegerRepresentation() &&
8521       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8522         return LIS.IsStrictCompare;
8523       });
8524   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8525   // unsigned IV)) for worksharing loops.
8526   SourceLocation CondLoc = AStmt->getBeginLoc();
8527   Expr *BoundUB = UB.get();
8528   if (UseStrictCompare) {
8529     BoundUB =
8530         SemaRef
8531             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8532                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8533             .get();
8534     BoundUB =
8535         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8536   }
8537   ExprResult Cond =
8538       (isOpenMPWorksharingDirective(DKind) ||
8539        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8540           ? SemaRef.BuildBinOp(CurScope, CondLoc,
8541                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8542                                BoundUB)
8543           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8544                                NumIterations.get());
8545   ExprResult CombDistCond;
8546   if (isOpenMPLoopBoundSharingDirective(DKind)) {
8547     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8548                                       NumIterations.get());
8549   }
8550 
8551   ExprResult CombCond;
8552   if (isOpenMPLoopBoundSharingDirective(DKind)) {
8553     Expr *BoundCombUB = CombUB.get();
8554     if (UseStrictCompare) {
8555       BoundCombUB =
8556           SemaRef
8557               .BuildBinOp(
8558                   CurScope, CondLoc, BO_Add, BoundCombUB,
8559                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8560               .get();
8561       BoundCombUB =
8562           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8563               .get();
8564     }
8565     CombCond =
8566         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8567                            IV.get(), BoundCombUB);
8568   }
8569   // Loop increment (IV = IV + 1)
8570   SourceLocation IncLoc = AStmt->getBeginLoc();
8571   ExprResult Inc =
8572       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8573                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8574   if (!Inc.isUsable())
8575     return 0;
8576   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8577   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8578   if (!Inc.isUsable())
8579     return 0;
8580 
8581   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8582   // Used for directives with static scheduling.
8583   // In combined construct, add combined version that use CombLB and CombUB
8584   // base variables for the update
8585   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8586   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8587       isOpenMPDistributeDirective(DKind)) {
8588     // LB + ST
8589     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8590     if (!NextLB.isUsable())
8591       return 0;
8592     // LB = LB + ST
8593     NextLB =
8594         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8595     NextLB =
8596         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8597     if (!NextLB.isUsable())
8598       return 0;
8599     // UB + ST
8600     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8601     if (!NextUB.isUsable())
8602       return 0;
8603     // UB = UB + ST
8604     NextUB =
8605         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8606     NextUB =
8607         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8608     if (!NextUB.isUsable())
8609       return 0;
8610     if (isOpenMPLoopBoundSharingDirective(DKind)) {
8611       CombNextLB =
8612           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8613       if (!NextLB.isUsable())
8614         return 0;
8615       // LB = LB + ST
8616       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8617                                       CombNextLB.get());
8618       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8619                                                /*DiscardedValue*/ false);
8620       if (!CombNextLB.isUsable())
8621         return 0;
8622       // UB + ST
8623       CombNextUB =
8624           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8625       if (!CombNextUB.isUsable())
8626         return 0;
8627       // UB = UB + ST
8628       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8629                                       CombNextUB.get());
8630       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8631                                                /*DiscardedValue*/ false);
8632       if (!CombNextUB.isUsable())
8633         return 0;
8634     }
8635   }
8636 
8637   // Create increment expression for distribute loop when combined in a same
8638   // directive with for as IV = IV + ST; ensure upper bound expression based
8639   // on PrevUB instead of NumIterations - used to implement 'for' when found
8640   // in combination with 'distribute', like in 'distribute parallel for'
8641   SourceLocation DistIncLoc = AStmt->getBeginLoc();
8642   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8643   if (isOpenMPLoopBoundSharingDirective(DKind)) {
8644     DistCond = SemaRef.BuildBinOp(
8645         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8646     assert(DistCond.isUsable() && "distribute cond expr was not built");
8647 
8648     DistInc =
8649         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8650     assert(DistInc.isUsable() && "distribute inc expr was not built");
8651     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8652                                  DistInc.get());
8653     DistInc =
8654         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8655     assert(DistInc.isUsable() && "distribute inc expr was not built");
8656 
8657     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8658     // construct
8659     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8660     ExprResult IsUBGreater =
8661         SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8662     ExprResult CondOp = SemaRef.ActOnConditionalOp(
8663         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8664     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8665                                  CondOp.get());
8666     PrevEUB =
8667         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8668 
8669     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8670     // parallel for is in combination with a distribute directive with
8671     // schedule(static, 1)
8672     Expr *BoundPrevUB = PrevUB.get();
8673     if (UseStrictCompare) {
8674       BoundPrevUB =
8675           SemaRef
8676               .BuildBinOp(
8677                   CurScope, CondLoc, BO_Add, BoundPrevUB,
8678                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8679               .get();
8680       BoundPrevUB =
8681           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8682               .get();
8683     }
8684     ParForInDistCond =
8685         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8686                            IV.get(), BoundPrevUB);
8687   }
8688 
8689   // Build updates and final values of the loop counters.
8690   bool HasErrors = false;
8691   Built.Counters.resize(NestedLoopCount);
8692   Built.Inits.resize(NestedLoopCount);
8693   Built.Updates.resize(NestedLoopCount);
8694   Built.Finals.resize(NestedLoopCount);
8695   Built.DependentCounters.resize(NestedLoopCount);
8696   Built.DependentInits.resize(NestedLoopCount);
8697   Built.FinalsConditions.resize(NestedLoopCount);
8698   {
8699     // We implement the following algorithm for obtaining the
8700     // original loop iteration variable values based on the
8701     // value of the collapsed loop iteration variable IV.
8702     //
8703     // Let n+1 be the number of collapsed loops in the nest.
8704     // Iteration variables (I0, I1, .... In)
8705     // Iteration counts (N0, N1, ... Nn)
8706     //
8707     // Acc = IV;
8708     //
8709     // To compute Ik for loop k, 0 <= k <= n, generate:
8710     //    Prod = N(k+1) * N(k+2) * ... * Nn;
8711     //    Ik = Acc / Prod;
8712     //    Acc -= Ik * Prod;
8713     //
8714     ExprResult Acc = IV;
8715     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8716       LoopIterationSpace &IS = IterSpaces[Cnt];
8717       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8718       ExprResult Iter;
8719 
8720       // Compute prod
8721       ExprResult Prod =
8722           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8723       for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8724         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8725                                   IterSpaces[K].NumIterations);
8726 
8727       // Iter = Acc / Prod
8728       // If there is at least one more inner loop to avoid
8729       // multiplication by 1.
8730       if (Cnt + 1 < NestedLoopCount)
8731         Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8732                                   Acc.get(), Prod.get());
8733       else
8734         Iter = Acc;
8735       if (!Iter.isUsable()) {
8736         HasErrors = true;
8737         break;
8738       }
8739 
8740       // Update Acc:
8741       // Acc -= Iter * Prod
8742       // Check if there is at least one more inner loop to avoid
8743       // multiplication by 1.
8744       if (Cnt + 1 < NestedLoopCount)
8745         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8746                                   Iter.get(), Prod.get());
8747       else
8748         Prod = Iter;
8749       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8750                                Acc.get(), Prod.get());
8751 
8752       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8753       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8754       DeclRefExpr *CounterVar = buildDeclRefExpr(
8755           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8756           /*RefersToCapture=*/true);
8757       ExprResult Init =
8758           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8759                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
8760       if (!Init.isUsable()) {
8761         HasErrors = true;
8762         break;
8763       }
8764       ExprResult Update = buildCounterUpdate(
8765           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8766           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8767       if (!Update.isUsable()) {
8768         HasErrors = true;
8769         break;
8770       }
8771 
8772       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8773       ExprResult Final =
8774           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8775                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
8776                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
8777       if (!Final.isUsable()) {
8778         HasErrors = true;
8779         break;
8780       }
8781 
8782       if (!Update.isUsable() || !Final.isUsable()) {
8783         HasErrors = true;
8784         break;
8785       }
8786       // Save results
8787       Built.Counters[Cnt] = IS.CounterVar;
8788       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8789       Built.Inits[Cnt] = Init.get();
8790       Built.Updates[Cnt] = Update.get();
8791       Built.Finals[Cnt] = Final.get();
8792       Built.DependentCounters[Cnt] = nullptr;
8793       Built.DependentInits[Cnt] = nullptr;
8794       Built.FinalsConditions[Cnt] = nullptr;
8795       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8796         Built.DependentCounters[Cnt] =
8797             Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8798         Built.DependentInits[Cnt] =
8799             Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8800         Built.FinalsConditions[Cnt] = IS.FinalCondition;
8801       }
8802     }
8803   }
8804 
8805   if (HasErrors)
8806     return 0;
8807 
8808   // Save results
8809   Built.IterationVarRef = IV.get();
8810   Built.LastIteration = LastIteration.get();
8811   Built.NumIterations = NumIterations.get();
8812   Built.CalcLastIteration = SemaRef
8813                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
8814                                                      /*DiscardedValue=*/false)
8815                                 .get();
8816   Built.PreCond = PreCond.get();
8817   Built.PreInits = buildPreInits(C, Captures);
8818   Built.Cond = Cond.get();
8819   Built.Init = Init.get();
8820   Built.Inc = Inc.get();
8821   Built.LB = LB.get();
8822   Built.UB = UB.get();
8823   Built.IL = IL.get();
8824   Built.ST = ST.get();
8825   Built.EUB = EUB.get();
8826   Built.NLB = NextLB.get();
8827   Built.NUB = NextUB.get();
8828   Built.PrevLB = PrevLB.get();
8829   Built.PrevUB = PrevUB.get();
8830   Built.DistInc = DistInc.get();
8831   Built.PrevEUB = PrevEUB.get();
8832   Built.DistCombinedFields.LB = CombLB.get();
8833   Built.DistCombinedFields.UB = CombUB.get();
8834   Built.DistCombinedFields.EUB = CombEUB.get();
8835   Built.DistCombinedFields.Init = CombInit.get();
8836   Built.DistCombinedFields.Cond = CombCond.get();
8837   Built.DistCombinedFields.NLB = CombNextLB.get();
8838   Built.DistCombinedFields.NUB = CombNextUB.get();
8839   Built.DistCombinedFields.DistCond = CombDistCond.get();
8840   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8841 
8842   return NestedLoopCount;
8843 }
8844 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)8845 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8846   auto CollapseClauses =
8847       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8848   if (CollapseClauses.begin() != CollapseClauses.end())
8849     return (*CollapseClauses.begin())->getNumForLoops();
8850   return nullptr;
8851 }
8852 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)8853 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8854   auto OrderedClauses =
8855       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8856   if (OrderedClauses.begin() != OrderedClauses.end())
8857     return (*OrderedClauses.begin())->getNumForLoops();
8858   return nullptr;
8859 }
8860 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)8861 static bool checkSimdlenSafelenSpecified(Sema &S,
8862                                          const ArrayRef<OMPClause *> Clauses) {
8863   const OMPSafelenClause *Safelen = nullptr;
8864   const OMPSimdlenClause *Simdlen = nullptr;
8865 
8866   for (const OMPClause *Clause : Clauses) {
8867     if (Clause->getClauseKind() == OMPC_safelen)
8868       Safelen = cast<OMPSafelenClause>(Clause);
8869     else if (Clause->getClauseKind() == OMPC_simdlen)
8870       Simdlen = cast<OMPSimdlenClause>(Clause);
8871     if (Safelen && Simdlen)
8872       break;
8873   }
8874 
8875   if (Simdlen && Safelen) {
8876     const Expr *SimdlenLength = Simdlen->getSimdlen();
8877     const Expr *SafelenLength = Safelen->getSafelen();
8878     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8879         SimdlenLength->isInstantiationDependent() ||
8880         SimdlenLength->containsUnexpandedParameterPack())
8881       return false;
8882     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8883         SafelenLength->isInstantiationDependent() ||
8884         SafelenLength->containsUnexpandedParameterPack())
8885       return false;
8886     Expr::EvalResult SimdlenResult, SafelenResult;
8887     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8888     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8889     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8890     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8891     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8892     // If both simdlen and safelen clauses are specified, the value of the
8893     // simdlen parameter must be less than or equal to the value of the safelen
8894     // parameter.
8895     if (SimdlenRes > SafelenRes) {
8896       S.Diag(SimdlenLength->getExprLoc(),
8897              diag::err_omp_wrong_simdlen_safelen_values)
8898           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8899       return true;
8900     }
8901   }
8902   return false;
8903 }
8904 
8905 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8906 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8907                                SourceLocation StartLoc, SourceLocation EndLoc,
8908                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8909   if (!AStmt)
8910     return StmtError();
8911 
8912   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8913   OMPLoopDirective::HelperExprs B;
8914   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8915   // define the nested loops number.
8916   unsigned NestedLoopCount = checkOpenMPLoop(
8917       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8918       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8919   if (NestedLoopCount == 0)
8920     return StmtError();
8921 
8922   assert((CurContext->isDependentContext() || B.builtAll()) &&
8923          "omp simd loop exprs were not built");
8924 
8925   if (!CurContext->isDependentContext()) {
8926     // Finalize the clauses that need pre-built expressions for CodeGen.
8927     for (OMPClause *C : Clauses) {
8928       if (auto *LC = dyn_cast<OMPLinearClause>(C))
8929         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8930                                      B.NumIterations, *this, CurScope,
8931                                      DSAStack))
8932           return StmtError();
8933     }
8934   }
8935 
8936   if (checkSimdlenSafelenSpecified(*this, Clauses))
8937     return StmtError();
8938 
8939   setFunctionHasBranchProtectedScope();
8940   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8941                                   Clauses, AStmt, B);
8942 }
8943 
8944 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8945 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8946                               SourceLocation StartLoc, SourceLocation EndLoc,
8947                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8948   if (!AStmt)
8949     return StmtError();
8950 
8951   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8952   OMPLoopDirective::HelperExprs B;
8953   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8954   // define the nested loops number.
8955   unsigned NestedLoopCount = checkOpenMPLoop(
8956       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8957       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8958   if (NestedLoopCount == 0)
8959     return StmtError();
8960 
8961   assert((CurContext->isDependentContext() || B.builtAll()) &&
8962          "omp for loop exprs were not built");
8963 
8964   if (!CurContext->isDependentContext()) {
8965     // Finalize the clauses that need pre-built expressions for CodeGen.
8966     for (OMPClause *C : Clauses) {
8967       if (auto *LC = dyn_cast<OMPLinearClause>(C))
8968         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8969                                      B.NumIterations, *this, CurScope,
8970                                      DSAStack))
8971           return StmtError();
8972     }
8973   }
8974 
8975   setFunctionHasBranchProtectedScope();
8976   return OMPForDirective::Create(
8977       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8978       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
8979 }
8980 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)8981 StmtResult Sema::ActOnOpenMPForSimdDirective(
8982     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8983     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8984   if (!AStmt)
8985     return StmtError();
8986 
8987   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8988   OMPLoopDirective::HelperExprs B;
8989   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8990   // define the nested loops number.
8991   unsigned NestedLoopCount =
8992       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8993                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8994                       VarsWithImplicitDSA, B);
8995   if (NestedLoopCount == 0)
8996     return StmtError();
8997 
8998   assert((CurContext->isDependentContext() || B.builtAll()) &&
8999          "omp for simd loop exprs were not built");
9000 
9001   if (!CurContext->isDependentContext()) {
9002     // Finalize the clauses that need pre-built expressions for CodeGen.
9003     for (OMPClause *C : Clauses) {
9004       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9005         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9006                                      B.NumIterations, *this, CurScope,
9007                                      DSAStack))
9008           return StmtError();
9009     }
9010   }
9011 
9012   if (checkSimdlenSafelenSpecified(*this, Clauses))
9013     return StmtError();
9014 
9015   setFunctionHasBranchProtectedScope();
9016   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9017                                      Clauses, AStmt, B);
9018 }
9019 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9020 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9021                                               Stmt *AStmt,
9022                                               SourceLocation StartLoc,
9023                                               SourceLocation EndLoc) {
9024   if (!AStmt)
9025     return StmtError();
9026 
9027   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9028   auto BaseStmt = AStmt;
9029   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9030     BaseStmt = CS->getCapturedStmt();
9031   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9032     auto S = C->children();
9033     if (S.begin() == S.end())
9034       return StmtError();
9035     // All associated statements must be '#pragma omp section' except for
9036     // the first one.
9037     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9038       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9039         if (SectionStmt)
9040           Diag(SectionStmt->getBeginLoc(),
9041                diag::err_omp_sections_substmt_not_section);
9042         return StmtError();
9043       }
9044       cast<OMPSectionDirective>(SectionStmt)
9045           ->setHasCancel(DSAStack->isCancelRegion());
9046     }
9047   } else {
9048     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9049     return StmtError();
9050   }
9051 
9052   setFunctionHasBranchProtectedScope();
9053 
9054   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9055                                       DSAStack->getTaskgroupReductionRef(),
9056                                       DSAStack->isCancelRegion());
9057 }
9058 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9059 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9060                                              SourceLocation StartLoc,
9061                                              SourceLocation EndLoc) {
9062   if (!AStmt)
9063     return StmtError();
9064 
9065   setFunctionHasBranchProtectedScope();
9066   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9067 
9068   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9069                                      DSAStack->isCancelRegion());
9070 }
9071 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9072 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9073                                             Stmt *AStmt,
9074                                             SourceLocation StartLoc,
9075                                             SourceLocation EndLoc) {
9076   if (!AStmt)
9077     return StmtError();
9078 
9079   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9080 
9081   setFunctionHasBranchProtectedScope();
9082 
9083   // OpenMP [2.7.3, single Construct, Restrictions]
9084   // The copyprivate clause must not be used with the nowait clause.
9085   const OMPClause *Nowait = nullptr;
9086   const OMPClause *Copyprivate = nullptr;
9087   for (const OMPClause *Clause : Clauses) {
9088     if (Clause->getClauseKind() == OMPC_nowait)
9089       Nowait = Clause;
9090     else if (Clause->getClauseKind() == OMPC_copyprivate)
9091       Copyprivate = Clause;
9092     if (Copyprivate && Nowait) {
9093       Diag(Copyprivate->getBeginLoc(),
9094            diag::err_omp_single_copyprivate_with_nowait);
9095       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9096       return StmtError();
9097     }
9098   }
9099 
9100   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9101 }
9102 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9103 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9104                                             SourceLocation StartLoc,
9105                                             SourceLocation EndLoc) {
9106   if (!AStmt)
9107     return StmtError();
9108 
9109   setFunctionHasBranchProtectedScope();
9110 
9111   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9112 }
9113 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9114 StmtResult Sema::ActOnOpenMPCriticalDirective(
9115     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9116     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9117   if (!AStmt)
9118     return StmtError();
9119 
9120   bool ErrorFound = false;
9121   llvm::APSInt Hint;
9122   SourceLocation HintLoc;
9123   bool DependentHint = false;
9124   for (const OMPClause *C : Clauses) {
9125     if (C->getClauseKind() == OMPC_hint) {
9126       if (!DirName.getName()) {
9127         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9128         ErrorFound = true;
9129       }
9130       Expr *E = cast<OMPHintClause>(C)->getHint();
9131       if (E->isTypeDependent() || E->isValueDependent() ||
9132           E->isInstantiationDependent()) {
9133         DependentHint = true;
9134       } else {
9135         Hint = E->EvaluateKnownConstInt(Context);
9136         HintLoc = C->getBeginLoc();
9137       }
9138     }
9139   }
9140   if (ErrorFound)
9141     return StmtError();
9142   const auto Pair = DSAStack->getCriticalWithHint(DirName);
9143   if (Pair.first && DirName.getName() && !DependentHint) {
9144     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9145       Diag(StartLoc, diag::err_omp_critical_with_hint);
9146       if (HintLoc.isValid())
9147         Diag(HintLoc, diag::note_omp_critical_hint_here)
9148             << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9149       else
9150         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9151       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9152         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9153             << 1
9154             << C->getHint()->EvaluateKnownConstInt(Context).toString(
9155                    /*Radix=*/10, /*Signed=*/false);
9156       } else {
9157         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9158       }
9159     }
9160   }
9161 
9162   setFunctionHasBranchProtectedScope();
9163 
9164   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9165                                            Clauses, AStmt);
9166   if (!Pair.first && DirName.getName() && !DependentHint)
9167     DSAStack->addCriticalWithHint(Dir, Hint);
9168   return Dir;
9169 }
9170 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9171 StmtResult Sema::ActOnOpenMPParallelForDirective(
9172     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9173     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9174   if (!AStmt)
9175     return StmtError();
9176 
9177   auto *CS = cast<CapturedStmt>(AStmt);
9178   // 1.2.2 OpenMP Language Terminology
9179   // Structured block - An executable statement with a single entry at the
9180   // top and a single exit at the bottom.
9181   // The point of exit cannot be a branch out of the structured block.
9182   // longjmp() and throw() must not violate the entry/exit criteria.
9183   CS->getCapturedDecl()->setNothrow();
9184 
9185   OMPLoopDirective::HelperExprs B;
9186   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9187   // define the nested loops number.
9188   unsigned NestedLoopCount =
9189       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9190                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9191                       VarsWithImplicitDSA, B);
9192   if (NestedLoopCount == 0)
9193     return StmtError();
9194 
9195   assert((CurContext->isDependentContext() || B.builtAll()) &&
9196          "omp parallel for loop exprs were not built");
9197 
9198   if (!CurContext->isDependentContext()) {
9199     // Finalize the clauses that need pre-built expressions for CodeGen.
9200     for (OMPClause *C : Clauses) {
9201       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9202         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9203                                      B.NumIterations, *this, CurScope,
9204                                      DSAStack))
9205           return StmtError();
9206     }
9207   }
9208 
9209   setFunctionHasBranchProtectedScope();
9210   return OMPParallelForDirective::Create(
9211       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9212       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9213 }
9214 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9215 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9216     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9217     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9218   if (!AStmt)
9219     return StmtError();
9220 
9221   auto *CS = cast<CapturedStmt>(AStmt);
9222   // 1.2.2 OpenMP Language Terminology
9223   // Structured block - An executable statement with a single entry at the
9224   // top and a single exit at the bottom.
9225   // The point of exit cannot be a branch out of the structured block.
9226   // longjmp() and throw() must not violate the entry/exit criteria.
9227   CS->getCapturedDecl()->setNothrow();
9228 
9229   OMPLoopDirective::HelperExprs B;
9230   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9231   // define the nested loops number.
9232   unsigned NestedLoopCount =
9233       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9234                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9235                       VarsWithImplicitDSA, B);
9236   if (NestedLoopCount == 0)
9237     return StmtError();
9238 
9239   if (!CurContext->isDependentContext()) {
9240     // Finalize the clauses that need pre-built expressions for CodeGen.
9241     for (OMPClause *C : Clauses) {
9242       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9243         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9244                                      B.NumIterations, *this, CurScope,
9245                                      DSAStack))
9246           return StmtError();
9247     }
9248   }
9249 
9250   if (checkSimdlenSafelenSpecified(*this, Clauses))
9251     return StmtError();
9252 
9253   setFunctionHasBranchProtectedScope();
9254   return OMPParallelForSimdDirective::Create(
9255       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9256 }
9257 
9258 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9259 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9260                                          Stmt *AStmt, SourceLocation StartLoc,
9261                                          SourceLocation EndLoc) {
9262   if (!AStmt)
9263     return StmtError();
9264 
9265   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9266   auto *CS = cast<CapturedStmt>(AStmt);
9267   // 1.2.2 OpenMP Language Terminology
9268   // Structured block - An executable statement with a single entry at the
9269   // top and a single exit at the bottom.
9270   // The point of exit cannot be a branch out of the structured block.
9271   // longjmp() and throw() must not violate the entry/exit criteria.
9272   CS->getCapturedDecl()->setNothrow();
9273 
9274   setFunctionHasBranchProtectedScope();
9275 
9276   return OMPParallelMasterDirective::Create(
9277       Context, StartLoc, EndLoc, Clauses, AStmt,
9278       DSAStack->getTaskgroupReductionRef());
9279 }
9280 
9281 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9282 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9283                                            Stmt *AStmt, SourceLocation StartLoc,
9284                                            SourceLocation EndLoc) {
9285   if (!AStmt)
9286     return StmtError();
9287 
9288   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9289   auto BaseStmt = AStmt;
9290   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9291     BaseStmt = CS->getCapturedStmt();
9292   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9293     auto S = C->children();
9294     if (S.begin() == S.end())
9295       return StmtError();
9296     // All associated statements must be '#pragma omp section' except for
9297     // the first one.
9298     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9299       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9300         if (SectionStmt)
9301           Diag(SectionStmt->getBeginLoc(),
9302                diag::err_omp_parallel_sections_substmt_not_section);
9303         return StmtError();
9304       }
9305       cast<OMPSectionDirective>(SectionStmt)
9306           ->setHasCancel(DSAStack->isCancelRegion());
9307     }
9308   } else {
9309     Diag(AStmt->getBeginLoc(),
9310          diag::err_omp_parallel_sections_not_compound_stmt);
9311     return StmtError();
9312   }
9313 
9314   setFunctionHasBranchProtectedScope();
9315 
9316   return OMPParallelSectionsDirective::Create(
9317       Context, StartLoc, EndLoc, Clauses, AStmt,
9318       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9319 }
9320 
9321 /// detach and mergeable clauses are mutially exclusive, check for it.
checkDetachMergeableClauses(Sema & S,ArrayRef<OMPClause * > Clauses)9322 static bool checkDetachMergeableClauses(Sema &S,
9323                                         ArrayRef<OMPClause *> Clauses) {
9324   const OMPClause *PrevClause = nullptr;
9325   bool ErrorFound = false;
9326   for (const OMPClause *C : Clauses) {
9327     if (C->getClauseKind() == OMPC_detach ||
9328         C->getClauseKind() == OMPC_mergeable) {
9329       if (!PrevClause) {
9330         PrevClause = C;
9331       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9332         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9333             << getOpenMPClauseName(C->getClauseKind())
9334             << getOpenMPClauseName(PrevClause->getClauseKind());
9335         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9336             << getOpenMPClauseName(PrevClause->getClauseKind());
9337         ErrorFound = true;
9338       }
9339     }
9340   }
9341   return ErrorFound;
9342 }
9343 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9344 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9345                                           Stmt *AStmt, SourceLocation StartLoc,
9346                                           SourceLocation EndLoc) {
9347   if (!AStmt)
9348     return StmtError();
9349 
9350   // OpenMP 5.0, 2.10.1 task Construct
9351   // If a detach clause appears on the directive, then a mergeable clause cannot
9352   // appear on the same directive.
9353   if (checkDetachMergeableClauses(*this, Clauses))
9354     return StmtError();
9355 
9356   auto *CS = cast<CapturedStmt>(AStmt);
9357   // 1.2.2 OpenMP Language Terminology
9358   // Structured block - An executable statement with a single entry at the
9359   // top and a single exit at the bottom.
9360   // The point of exit cannot be a branch out of the structured block.
9361   // longjmp() and throw() must not violate the entry/exit criteria.
9362   CS->getCapturedDecl()->setNothrow();
9363 
9364   setFunctionHasBranchProtectedScope();
9365 
9366   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9367                                   DSAStack->isCancelRegion());
9368 }
9369 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)9370 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9371                                                SourceLocation EndLoc) {
9372   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9373 }
9374 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)9375 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9376                                              SourceLocation EndLoc) {
9377   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9378 }
9379 
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)9380 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9381                                               SourceLocation EndLoc) {
9382   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9383 }
9384 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9385 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9386                                                Stmt *AStmt,
9387                                                SourceLocation StartLoc,
9388                                                SourceLocation EndLoc) {
9389   if (!AStmt)
9390     return StmtError();
9391 
9392   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9393 
9394   setFunctionHasBranchProtectedScope();
9395 
9396   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9397                                        AStmt,
9398                                        DSAStack->getTaskgroupReductionRef());
9399 }
9400 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9401 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9402                                            SourceLocation StartLoc,
9403                                            SourceLocation EndLoc) {
9404   OMPFlushClause *FC = nullptr;
9405   OMPClause *OrderClause = nullptr;
9406   for (OMPClause *C : Clauses) {
9407     if (C->getClauseKind() == OMPC_flush)
9408       FC = cast<OMPFlushClause>(C);
9409     else
9410       OrderClause = C;
9411   }
9412   OpenMPClauseKind MemOrderKind = OMPC_unknown;
9413   SourceLocation MemOrderLoc;
9414   for (const OMPClause *C : Clauses) {
9415     if (C->getClauseKind() == OMPC_acq_rel ||
9416         C->getClauseKind() == OMPC_acquire ||
9417         C->getClauseKind() == OMPC_release) {
9418       if (MemOrderKind != OMPC_unknown) {
9419         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9420             << getOpenMPDirectiveName(OMPD_flush) << 1
9421             << SourceRange(C->getBeginLoc(), C->getEndLoc());
9422         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9423             << getOpenMPClauseName(MemOrderKind);
9424       } else {
9425         MemOrderKind = C->getClauseKind();
9426         MemOrderLoc = C->getBeginLoc();
9427       }
9428     }
9429   }
9430   if (FC && OrderClause) {
9431     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9432         << getOpenMPClauseName(OrderClause->getClauseKind());
9433     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9434         << getOpenMPClauseName(OrderClause->getClauseKind());
9435     return StmtError();
9436   }
9437   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9438 }
9439 
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9440 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9441                                             SourceLocation StartLoc,
9442                                             SourceLocation EndLoc) {
9443   if (Clauses.empty()) {
9444     Diag(StartLoc, diag::err_omp_depobj_expected);
9445     return StmtError();
9446   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9447     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9448     return StmtError();
9449   }
9450   // Only depobj expression and another single clause is allowed.
9451   if (Clauses.size() > 2) {
9452     Diag(Clauses[2]->getBeginLoc(),
9453          diag::err_omp_depobj_single_clause_expected);
9454     return StmtError();
9455   } else if (Clauses.size() < 1) {
9456     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9457     return StmtError();
9458   }
9459   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9460 }
9461 
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)9462 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9463                                           SourceLocation StartLoc,
9464                                           SourceLocation EndLoc) {
9465   // Check that exactly one clause is specified.
9466   if (Clauses.size() != 1) {
9467     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9468          diag::err_omp_scan_single_clause_expected);
9469     return StmtError();
9470   }
9471   // Check that scan directive is used in the scopeof the OpenMP loop body.
9472   if (Scope *S = DSAStack->getCurScope()) {
9473     Scope *ParentS = S->getParent();
9474     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9475         !ParentS->getBreakParent()->isOpenMPLoopScope())
9476       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9477                        << getOpenMPDirectiveName(OMPD_scan) << 5);
9478   }
9479   // Check that only one instance of scan directives is used in the same outer
9480   // region.
9481   if (DSAStack->doesParentHasScanDirective()) {
9482     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9483     Diag(DSAStack->getParentScanDirectiveLoc(),
9484          diag::note_omp_previous_directive)
9485         << "scan";
9486     return StmtError();
9487   }
9488   DSAStack->setParentHasScanDirective(StartLoc);
9489   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9490 }
9491 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9492 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9493                                              Stmt *AStmt,
9494                                              SourceLocation StartLoc,
9495                                              SourceLocation EndLoc) {
9496   const OMPClause *DependFound = nullptr;
9497   const OMPClause *DependSourceClause = nullptr;
9498   const OMPClause *DependSinkClause = nullptr;
9499   bool ErrorFound = false;
9500   const OMPThreadsClause *TC = nullptr;
9501   const OMPSIMDClause *SC = nullptr;
9502   for (const OMPClause *C : Clauses) {
9503     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9504       DependFound = C;
9505       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9506         if (DependSourceClause) {
9507           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9508               << getOpenMPDirectiveName(OMPD_ordered)
9509               << getOpenMPClauseName(OMPC_depend) << 2;
9510           ErrorFound = true;
9511         } else {
9512           DependSourceClause = C;
9513         }
9514         if (DependSinkClause) {
9515           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9516               << 0;
9517           ErrorFound = true;
9518         }
9519       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9520         if (DependSourceClause) {
9521           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9522               << 1;
9523           ErrorFound = true;
9524         }
9525         DependSinkClause = C;
9526       }
9527     } else if (C->getClauseKind() == OMPC_threads) {
9528       TC = cast<OMPThreadsClause>(C);
9529     } else if (C->getClauseKind() == OMPC_simd) {
9530       SC = cast<OMPSIMDClause>(C);
9531     }
9532   }
9533   if (!ErrorFound && !SC &&
9534       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
9535     // OpenMP [2.8.1,simd Construct, Restrictions]
9536     // An ordered construct with the simd clause is the only OpenMP construct
9537     // that can appear in the simd region.
9538     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9539         << (LangOpts.OpenMP >= 50 ? 1 : 0);
9540     ErrorFound = true;
9541   } else if (DependFound && (TC || SC)) {
9542     Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9543         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9544     ErrorFound = true;
9545   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
9546     Diag(DependFound->getBeginLoc(),
9547          diag::err_omp_ordered_directive_without_param);
9548     ErrorFound = true;
9549   } else if (TC || Clauses.empty()) {
9550     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
9551       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9552       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9553           << (TC != nullptr);
9554       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9555       ErrorFound = true;
9556     }
9557   }
9558   if ((!AStmt && !DependFound) || ErrorFound)
9559     return StmtError();
9560 
9561   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9562   // During execution of an iteration of a worksharing-loop or a loop nest
9563   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9564   // must not execute more than one ordered region corresponding to an ordered
9565   // construct without a depend clause.
9566   if (!DependFound) {
9567     if (DSAStack->doesParentHasOrderedDirective()) {
9568       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9569       Diag(DSAStack->getParentOrderedDirectiveLoc(),
9570            diag::note_omp_previous_directive)
9571           << "ordered";
9572       return StmtError();
9573     }
9574     DSAStack->setParentHasOrderedDirective(StartLoc);
9575   }
9576 
9577   if (AStmt) {
9578     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9579 
9580     setFunctionHasBranchProtectedScope();
9581   }
9582 
9583   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9584 }
9585 
9586 namespace {
9587 /// Helper class for checking expression in 'omp atomic [update]'
9588 /// construct.
9589 class OpenMPAtomicUpdateChecker {
9590   /// Error results for atomic update expressions.
9591   enum ExprAnalysisErrorCode {
9592     /// A statement is not an expression statement.
9593     NotAnExpression,
9594     /// Expression is not builtin binary or unary operation.
9595     NotABinaryOrUnaryExpression,
9596     /// Unary operation is not post-/pre- increment/decrement operation.
9597     NotAnUnaryIncDecExpression,
9598     /// An expression is not of scalar type.
9599     NotAScalarType,
9600     /// A binary operation is not an assignment operation.
9601     NotAnAssignmentOp,
9602     /// RHS part of the binary operation is not a binary expression.
9603     NotABinaryExpression,
9604     /// RHS part is not additive/multiplicative/shift/biwise binary
9605     /// expression.
9606     NotABinaryOperator,
9607     /// RHS binary operation does not have reference to the updated LHS
9608     /// part.
9609     NotAnUpdateExpression,
9610     /// No errors is found.
9611     NoError
9612   };
9613   /// Reference to Sema.
9614   Sema &SemaRef;
9615   /// A location for note diagnostics (when error is found).
9616   SourceLocation NoteLoc;
9617   /// 'x' lvalue part of the source atomic expression.
9618   Expr *X;
9619   /// 'expr' rvalue part of the source atomic expression.
9620   Expr *E;
9621   /// Helper expression of the form
9622   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9623   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9624   Expr *UpdateExpr;
9625   /// Is 'x' a LHS in a RHS part of full update expression. It is
9626   /// important for non-associative operations.
9627   bool IsXLHSInRHSPart;
9628   BinaryOperatorKind Op;
9629   SourceLocation OpLoc;
9630   /// true if the source expression is a postfix unary operation, false
9631   /// if it is a prefix unary operation.
9632   bool IsPostfixUpdate;
9633 
9634 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)9635   OpenMPAtomicUpdateChecker(Sema &SemaRef)
9636       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9637         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9638   /// Check specified statement that it is suitable for 'atomic update'
9639   /// constructs and extract 'x', 'expr' and Operation from the original
9640   /// expression. If DiagId and NoteId == 0, then only check is performed
9641   /// without error notification.
9642   /// \param DiagId Diagnostic which should be emitted if error is found.
9643   /// \param NoteId Diagnostic note for the main error message.
9644   /// \return true if statement is not an update expression, false otherwise.
9645   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9646   /// Return the 'x' lvalue part of the source atomic expression.
getX() const9647   Expr *getX() const { return X; }
9648   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const9649   Expr *getExpr() const { return E; }
9650   /// Return the update expression used in calculation of the updated
9651   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9652   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const9653   Expr *getUpdateExpr() const { return UpdateExpr; }
9654   /// Return true if 'x' is LHS in RHS part of full update expression,
9655   /// false otherwise.
isXLHSInRHSPart() const9656   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9657 
9658   /// true if the source expression is a postfix unary operation, false
9659   /// if it is a prefix unary operation.
isPostfixUpdate() const9660   bool isPostfixUpdate() const { return IsPostfixUpdate; }
9661 
9662 private:
9663   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9664                             unsigned NoteId = 0);
9665 };
9666 } // namespace
9667 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)9668 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9669     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9670   ExprAnalysisErrorCode ErrorFound = NoError;
9671   SourceLocation ErrorLoc, NoteLoc;
9672   SourceRange ErrorRange, NoteRange;
9673   // Allowed constructs are:
9674   //  x = x binop expr;
9675   //  x = expr binop x;
9676   if (AtomicBinOp->getOpcode() == BO_Assign) {
9677     X = AtomicBinOp->getLHS();
9678     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9679             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9680       if (AtomicInnerBinOp->isMultiplicativeOp() ||
9681           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9682           AtomicInnerBinOp->isBitwiseOp()) {
9683         Op = AtomicInnerBinOp->getOpcode();
9684         OpLoc = AtomicInnerBinOp->getOperatorLoc();
9685         Expr *LHS = AtomicInnerBinOp->getLHS();
9686         Expr *RHS = AtomicInnerBinOp->getRHS();
9687         llvm::FoldingSetNodeID XId, LHSId, RHSId;
9688         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9689                                           /*Canonical=*/true);
9690         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9691                                             /*Canonical=*/true);
9692         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9693                                             /*Canonical=*/true);
9694         if (XId == LHSId) {
9695           E = RHS;
9696           IsXLHSInRHSPart = true;
9697         } else if (XId == RHSId) {
9698           E = LHS;
9699           IsXLHSInRHSPart = false;
9700         } else {
9701           ErrorLoc = AtomicInnerBinOp->getExprLoc();
9702           ErrorRange = AtomicInnerBinOp->getSourceRange();
9703           NoteLoc = X->getExprLoc();
9704           NoteRange = X->getSourceRange();
9705           ErrorFound = NotAnUpdateExpression;
9706         }
9707       } else {
9708         ErrorLoc = AtomicInnerBinOp->getExprLoc();
9709         ErrorRange = AtomicInnerBinOp->getSourceRange();
9710         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9711         NoteRange = SourceRange(NoteLoc, NoteLoc);
9712         ErrorFound = NotABinaryOperator;
9713       }
9714     } else {
9715       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9716       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9717       ErrorFound = NotABinaryExpression;
9718     }
9719   } else {
9720     ErrorLoc = AtomicBinOp->getExprLoc();
9721     ErrorRange = AtomicBinOp->getSourceRange();
9722     NoteLoc = AtomicBinOp->getOperatorLoc();
9723     NoteRange = SourceRange(NoteLoc, NoteLoc);
9724     ErrorFound = NotAnAssignmentOp;
9725   }
9726   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9727     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9728     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9729     return true;
9730   }
9731   if (SemaRef.CurContext->isDependentContext())
9732     E = X = UpdateExpr = nullptr;
9733   return ErrorFound != NoError;
9734 }
9735 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)9736 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9737                                                unsigned NoteId) {
9738   ExprAnalysisErrorCode ErrorFound = NoError;
9739   SourceLocation ErrorLoc, NoteLoc;
9740   SourceRange ErrorRange, NoteRange;
9741   // Allowed constructs are:
9742   //  x++;
9743   //  x--;
9744   //  ++x;
9745   //  --x;
9746   //  x binop= expr;
9747   //  x = x binop expr;
9748   //  x = expr binop x;
9749   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9750     AtomicBody = AtomicBody->IgnoreParenImpCasts();
9751     if (AtomicBody->getType()->isScalarType() ||
9752         AtomicBody->isInstantiationDependent()) {
9753       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9754               AtomicBody->IgnoreParenImpCasts())) {
9755         // Check for Compound Assignment Operation
9756         Op = BinaryOperator::getOpForCompoundAssignment(
9757             AtomicCompAssignOp->getOpcode());
9758         OpLoc = AtomicCompAssignOp->getOperatorLoc();
9759         E = AtomicCompAssignOp->getRHS();
9760         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9761         IsXLHSInRHSPart = true;
9762       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9763                      AtomicBody->IgnoreParenImpCasts())) {
9764         // Check for Binary Operation
9765         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9766           return true;
9767       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9768                      AtomicBody->IgnoreParenImpCasts())) {
9769         // Check for Unary Operation
9770         if (AtomicUnaryOp->isIncrementDecrementOp()) {
9771           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9772           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9773           OpLoc = AtomicUnaryOp->getOperatorLoc();
9774           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9775           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9776           IsXLHSInRHSPart = true;
9777         } else {
9778           ErrorFound = NotAnUnaryIncDecExpression;
9779           ErrorLoc = AtomicUnaryOp->getExprLoc();
9780           ErrorRange = AtomicUnaryOp->getSourceRange();
9781           NoteLoc = AtomicUnaryOp->getOperatorLoc();
9782           NoteRange = SourceRange(NoteLoc, NoteLoc);
9783         }
9784       } else if (!AtomicBody->isInstantiationDependent()) {
9785         ErrorFound = NotABinaryOrUnaryExpression;
9786         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9787         NoteRange = ErrorRange = AtomicBody->getSourceRange();
9788       }
9789     } else {
9790       ErrorFound = NotAScalarType;
9791       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9792       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9793     }
9794   } else {
9795     ErrorFound = NotAnExpression;
9796     NoteLoc = ErrorLoc = S->getBeginLoc();
9797     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9798   }
9799   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9800     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9801     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9802     return true;
9803   }
9804   if (SemaRef.CurContext->isDependentContext())
9805     E = X = UpdateExpr = nullptr;
9806   if (ErrorFound == NoError && E && X) {
9807     // Build an update expression of form 'OpaqueValueExpr(x) binop
9808     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9809     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9810     auto *OVEX = new (SemaRef.getASTContext())
9811         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9812     auto *OVEExpr = new (SemaRef.getASTContext())
9813         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9814     ExprResult Update =
9815         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9816                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
9817     if (Update.isInvalid())
9818       return true;
9819     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9820                                                Sema::AA_Casting);
9821     if (Update.isInvalid())
9822       return true;
9823     UpdateExpr = Update.get();
9824   }
9825   return ErrorFound != NoError;
9826 }
9827 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9828 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9829                                             Stmt *AStmt,
9830                                             SourceLocation StartLoc,
9831                                             SourceLocation EndLoc) {
9832   // Register location of the first atomic directive.
9833   DSAStack->addAtomicDirectiveLoc(StartLoc);
9834   if (!AStmt)
9835     return StmtError();
9836 
9837   // 1.2.2 OpenMP Language Terminology
9838   // Structured block - An executable statement with a single entry at the
9839   // top and a single exit at the bottom.
9840   // The point of exit cannot be a branch out of the structured block.
9841   // longjmp() and throw() must not violate the entry/exit criteria.
9842   OpenMPClauseKind AtomicKind = OMPC_unknown;
9843   SourceLocation AtomicKindLoc;
9844   OpenMPClauseKind MemOrderKind = OMPC_unknown;
9845   SourceLocation MemOrderLoc;
9846   for (const OMPClause *C : Clauses) {
9847     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9848         C->getClauseKind() == OMPC_update ||
9849         C->getClauseKind() == OMPC_capture) {
9850       if (AtomicKind != OMPC_unknown) {
9851         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9852             << SourceRange(C->getBeginLoc(), C->getEndLoc());
9853         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9854             << getOpenMPClauseName(AtomicKind);
9855       } else {
9856         AtomicKind = C->getClauseKind();
9857         AtomicKindLoc = C->getBeginLoc();
9858       }
9859     }
9860     if (C->getClauseKind() == OMPC_seq_cst ||
9861         C->getClauseKind() == OMPC_acq_rel ||
9862         C->getClauseKind() == OMPC_acquire ||
9863         C->getClauseKind() == OMPC_release ||
9864         C->getClauseKind() == OMPC_relaxed) {
9865       if (MemOrderKind != OMPC_unknown) {
9866         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9867             << getOpenMPDirectiveName(OMPD_atomic) << 0
9868             << SourceRange(C->getBeginLoc(), C->getEndLoc());
9869         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9870             << getOpenMPClauseName(MemOrderKind);
9871       } else {
9872         MemOrderKind = C->getClauseKind();
9873         MemOrderLoc = C->getBeginLoc();
9874       }
9875     }
9876   }
9877   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9878   // If atomic-clause is read then memory-order-clause must not be acq_rel or
9879   // release.
9880   // If atomic-clause is write then memory-order-clause must not be acq_rel or
9881   // acquire.
9882   // If atomic-clause is update or not present then memory-order-clause must not
9883   // be acq_rel or acquire.
9884   if ((AtomicKind == OMPC_read &&
9885        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9886       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9887         AtomicKind == OMPC_unknown) &&
9888        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9889     SourceLocation Loc = AtomicKindLoc;
9890     if (AtomicKind == OMPC_unknown)
9891       Loc = StartLoc;
9892     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9893         << getOpenMPClauseName(AtomicKind)
9894         << (AtomicKind == OMPC_unknown ? 1 : 0)
9895         << getOpenMPClauseName(MemOrderKind);
9896     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9897         << getOpenMPClauseName(MemOrderKind);
9898   }
9899 
9900   Stmt *Body = AStmt;
9901   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9902     Body = EWC->getSubExpr();
9903 
9904   Expr *X = nullptr;
9905   Expr *V = nullptr;
9906   Expr *E = nullptr;
9907   Expr *UE = nullptr;
9908   bool IsXLHSInRHSPart = false;
9909   bool IsPostfixUpdate = false;
9910   // OpenMP [2.12.6, atomic Construct]
9911   // In the next expressions:
9912   // * x and v (as applicable) are both l-value expressions with scalar type.
9913   // * During the execution of an atomic region, multiple syntactic
9914   // occurrences of x must designate the same storage location.
9915   // * Neither of v and expr (as applicable) may access the storage location
9916   // designated by x.
9917   // * Neither of x and expr (as applicable) may access the storage location
9918   // designated by v.
9919   // * expr is an expression with scalar type.
9920   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9921   // * binop, binop=, ++, and -- are not overloaded operators.
9922   // * The expression x binop expr must be numerically equivalent to x binop
9923   // (expr). This requirement is satisfied if the operators in expr have
9924   // precedence greater than binop, or by using parentheses around expr or
9925   // subexpressions of expr.
9926   // * The expression expr binop x must be numerically equivalent to (expr)
9927   // binop x. This requirement is satisfied if the operators in expr have
9928   // precedence equal to or greater than binop, or by using parentheses around
9929   // expr or subexpressions of expr.
9930   // * For forms that allow multiple occurrences of x, the number of times
9931   // that x is evaluated is unspecified.
9932   if (AtomicKind == OMPC_read) {
9933     enum {
9934       NotAnExpression,
9935       NotAnAssignmentOp,
9936       NotAScalarType,
9937       NotAnLValue,
9938       NoError
9939     } ErrorFound = NoError;
9940     SourceLocation ErrorLoc, NoteLoc;
9941     SourceRange ErrorRange, NoteRange;
9942     // If clause is read:
9943     //  v = x;
9944     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9945       const auto *AtomicBinOp =
9946           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9947       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9948         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9949         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9950         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9951             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9952           if (!X->isLValue() || !V->isLValue()) {
9953             const Expr *NotLValueExpr = X->isLValue() ? V : X;
9954             ErrorFound = NotAnLValue;
9955             ErrorLoc = AtomicBinOp->getExprLoc();
9956             ErrorRange = AtomicBinOp->getSourceRange();
9957             NoteLoc = NotLValueExpr->getExprLoc();
9958             NoteRange = NotLValueExpr->getSourceRange();
9959           }
9960         } else if (!X->isInstantiationDependent() ||
9961                    !V->isInstantiationDependent()) {
9962           const Expr *NotScalarExpr =
9963               (X->isInstantiationDependent() || X->getType()->isScalarType())
9964                   ? V
9965                   : X;
9966           ErrorFound = NotAScalarType;
9967           ErrorLoc = AtomicBinOp->getExprLoc();
9968           ErrorRange = AtomicBinOp->getSourceRange();
9969           NoteLoc = NotScalarExpr->getExprLoc();
9970           NoteRange = NotScalarExpr->getSourceRange();
9971         }
9972       } else if (!AtomicBody->isInstantiationDependent()) {
9973         ErrorFound = NotAnAssignmentOp;
9974         ErrorLoc = AtomicBody->getExprLoc();
9975         ErrorRange = AtomicBody->getSourceRange();
9976         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9977                               : AtomicBody->getExprLoc();
9978         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9979                                 : AtomicBody->getSourceRange();
9980       }
9981     } else {
9982       ErrorFound = NotAnExpression;
9983       NoteLoc = ErrorLoc = Body->getBeginLoc();
9984       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9985     }
9986     if (ErrorFound != NoError) {
9987       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9988           << ErrorRange;
9989       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9990                                                       << NoteRange;
9991       return StmtError();
9992     }
9993     if (CurContext->isDependentContext())
9994       V = X = nullptr;
9995   } else if (AtomicKind == OMPC_write) {
9996     enum {
9997       NotAnExpression,
9998       NotAnAssignmentOp,
9999       NotAScalarType,
10000       NotAnLValue,
10001       NoError
10002     } ErrorFound = NoError;
10003     SourceLocation ErrorLoc, NoteLoc;
10004     SourceRange ErrorRange, NoteRange;
10005     // If clause is write:
10006     //  x = expr;
10007     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10008       const auto *AtomicBinOp =
10009           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10010       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10011         X = AtomicBinOp->getLHS();
10012         E = AtomicBinOp->getRHS();
10013         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10014             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10015           if (!X->isLValue()) {
10016             ErrorFound = NotAnLValue;
10017             ErrorLoc = AtomicBinOp->getExprLoc();
10018             ErrorRange = AtomicBinOp->getSourceRange();
10019             NoteLoc = X->getExprLoc();
10020             NoteRange = X->getSourceRange();
10021           }
10022         } else if (!X->isInstantiationDependent() ||
10023                    !E->isInstantiationDependent()) {
10024           const Expr *NotScalarExpr =
10025               (X->isInstantiationDependent() || X->getType()->isScalarType())
10026                   ? E
10027                   : X;
10028           ErrorFound = NotAScalarType;
10029           ErrorLoc = AtomicBinOp->getExprLoc();
10030           ErrorRange = AtomicBinOp->getSourceRange();
10031           NoteLoc = NotScalarExpr->getExprLoc();
10032           NoteRange = NotScalarExpr->getSourceRange();
10033         }
10034       } else if (!AtomicBody->isInstantiationDependent()) {
10035         ErrorFound = NotAnAssignmentOp;
10036         ErrorLoc = AtomicBody->getExprLoc();
10037         ErrorRange = AtomicBody->getSourceRange();
10038         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10039                               : AtomicBody->getExprLoc();
10040         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10041                                 : AtomicBody->getSourceRange();
10042       }
10043     } else {
10044       ErrorFound = NotAnExpression;
10045       NoteLoc = ErrorLoc = Body->getBeginLoc();
10046       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10047     }
10048     if (ErrorFound != NoError) {
10049       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10050           << ErrorRange;
10051       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10052                                                       << NoteRange;
10053       return StmtError();
10054     }
10055     if (CurContext->isDependentContext())
10056       E = X = nullptr;
10057   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10058     // If clause is update:
10059     //  x++;
10060     //  x--;
10061     //  ++x;
10062     //  --x;
10063     //  x binop= expr;
10064     //  x = x binop expr;
10065     //  x = expr binop x;
10066     OpenMPAtomicUpdateChecker Checker(*this);
10067     if (Checker.checkStatement(
10068             Body, (AtomicKind == OMPC_update)
10069                       ? diag::err_omp_atomic_update_not_expression_statement
10070                       : diag::err_omp_atomic_not_expression_statement,
10071             diag::note_omp_atomic_update))
10072       return StmtError();
10073     if (!CurContext->isDependentContext()) {
10074       E = Checker.getExpr();
10075       X = Checker.getX();
10076       UE = Checker.getUpdateExpr();
10077       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10078     }
10079   } else if (AtomicKind == OMPC_capture) {
10080     enum {
10081       NotAnAssignmentOp,
10082       NotACompoundStatement,
10083       NotTwoSubstatements,
10084       NotASpecificExpression,
10085       NoError
10086     } ErrorFound = NoError;
10087     SourceLocation ErrorLoc, NoteLoc;
10088     SourceRange ErrorRange, NoteRange;
10089     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10090       // If clause is a capture:
10091       //  v = x++;
10092       //  v = x--;
10093       //  v = ++x;
10094       //  v = --x;
10095       //  v = x binop= expr;
10096       //  v = x = x binop expr;
10097       //  v = x = expr binop x;
10098       const auto *AtomicBinOp =
10099           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10100       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10101         V = AtomicBinOp->getLHS();
10102         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10103         OpenMPAtomicUpdateChecker Checker(*this);
10104         if (Checker.checkStatement(
10105                 Body, diag::err_omp_atomic_capture_not_expression_statement,
10106                 diag::note_omp_atomic_update))
10107           return StmtError();
10108         E = Checker.getExpr();
10109         X = Checker.getX();
10110         UE = Checker.getUpdateExpr();
10111         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10112         IsPostfixUpdate = Checker.isPostfixUpdate();
10113       } else if (!AtomicBody->isInstantiationDependent()) {
10114         ErrorLoc = AtomicBody->getExprLoc();
10115         ErrorRange = AtomicBody->getSourceRange();
10116         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10117                               : AtomicBody->getExprLoc();
10118         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10119                                 : AtomicBody->getSourceRange();
10120         ErrorFound = NotAnAssignmentOp;
10121       }
10122       if (ErrorFound != NoError) {
10123         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10124             << ErrorRange;
10125         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10126         return StmtError();
10127       }
10128       if (CurContext->isDependentContext())
10129         UE = V = E = X = nullptr;
10130     } else {
10131       // If clause is a capture:
10132       //  { v = x; x = expr; }
10133       //  { v = x; x++; }
10134       //  { v = x; x--; }
10135       //  { v = x; ++x; }
10136       //  { v = x; --x; }
10137       //  { v = x; x binop= expr; }
10138       //  { v = x; x = x binop expr; }
10139       //  { v = x; x = expr binop x; }
10140       //  { x++; v = x; }
10141       //  { x--; v = x; }
10142       //  { ++x; v = x; }
10143       //  { --x; v = x; }
10144       //  { x binop= expr; v = x; }
10145       //  { x = x binop expr; v = x; }
10146       //  { x = expr binop x; v = x; }
10147       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10148         // Check that this is { expr1; expr2; }
10149         if (CS->size() == 2) {
10150           Stmt *First = CS->body_front();
10151           Stmt *Second = CS->body_back();
10152           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10153             First = EWC->getSubExpr()->IgnoreParenImpCasts();
10154           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10155             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10156           // Need to find what subexpression is 'v' and what is 'x'.
10157           OpenMPAtomicUpdateChecker Checker(*this);
10158           bool IsUpdateExprFound = !Checker.checkStatement(Second);
10159           BinaryOperator *BinOp = nullptr;
10160           if (IsUpdateExprFound) {
10161             BinOp = dyn_cast<BinaryOperator>(First);
10162             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10163           }
10164           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10165             //  { v = x; x++; }
10166             //  { v = x; x--; }
10167             //  { v = x; ++x; }
10168             //  { v = x; --x; }
10169             //  { v = x; x binop= expr; }
10170             //  { v = x; x = x binop expr; }
10171             //  { v = x; x = expr binop x; }
10172             // Check that the first expression has form v = x.
10173             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10174             llvm::FoldingSetNodeID XId, PossibleXId;
10175             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10176             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10177             IsUpdateExprFound = XId == PossibleXId;
10178             if (IsUpdateExprFound) {
10179               V = BinOp->getLHS();
10180               X = Checker.getX();
10181               E = Checker.getExpr();
10182               UE = Checker.getUpdateExpr();
10183               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10184               IsPostfixUpdate = true;
10185             }
10186           }
10187           if (!IsUpdateExprFound) {
10188             IsUpdateExprFound = !Checker.checkStatement(First);
10189             BinOp = nullptr;
10190             if (IsUpdateExprFound) {
10191               BinOp = dyn_cast<BinaryOperator>(Second);
10192               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10193             }
10194             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10195               //  { x++; v = x; }
10196               //  { x--; v = x; }
10197               //  { ++x; v = x; }
10198               //  { --x; v = x; }
10199               //  { x binop= expr; v = x; }
10200               //  { x = x binop expr; v = x; }
10201               //  { x = expr binop x; v = x; }
10202               // Check that the second expression has form v = x.
10203               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10204               llvm::FoldingSetNodeID XId, PossibleXId;
10205               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10206               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10207               IsUpdateExprFound = XId == PossibleXId;
10208               if (IsUpdateExprFound) {
10209                 V = BinOp->getLHS();
10210                 X = Checker.getX();
10211                 E = Checker.getExpr();
10212                 UE = Checker.getUpdateExpr();
10213                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10214                 IsPostfixUpdate = false;
10215               }
10216             }
10217           }
10218           if (!IsUpdateExprFound) {
10219             //  { v = x; x = expr; }
10220             auto *FirstExpr = dyn_cast<Expr>(First);
10221             auto *SecondExpr = dyn_cast<Expr>(Second);
10222             if (!FirstExpr || !SecondExpr ||
10223                 !(FirstExpr->isInstantiationDependent() ||
10224                   SecondExpr->isInstantiationDependent())) {
10225               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10226               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10227                 ErrorFound = NotAnAssignmentOp;
10228                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10229                                                 : First->getBeginLoc();
10230                 NoteRange = ErrorRange = FirstBinOp
10231                                              ? FirstBinOp->getSourceRange()
10232                                              : SourceRange(ErrorLoc, ErrorLoc);
10233               } else {
10234                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10235                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10236                   ErrorFound = NotAnAssignmentOp;
10237                   NoteLoc = ErrorLoc = SecondBinOp
10238                                            ? SecondBinOp->getOperatorLoc()
10239                                            : Second->getBeginLoc();
10240                   NoteRange = ErrorRange =
10241                       SecondBinOp ? SecondBinOp->getSourceRange()
10242                                   : SourceRange(ErrorLoc, ErrorLoc);
10243                 } else {
10244                   Expr *PossibleXRHSInFirst =
10245                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
10246                   Expr *PossibleXLHSInSecond =
10247                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
10248                   llvm::FoldingSetNodeID X1Id, X2Id;
10249                   PossibleXRHSInFirst->Profile(X1Id, Context,
10250                                                /*Canonical=*/true);
10251                   PossibleXLHSInSecond->Profile(X2Id, Context,
10252                                                 /*Canonical=*/true);
10253                   IsUpdateExprFound = X1Id == X2Id;
10254                   if (IsUpdateExprFound) {
10255                     V = FirstBinOp->getLHS();
10256                     X = SecondBinOp->getLHS();
10257                     E = SecondBinOp->getRHS();
10258                     UE = nullptr;
10259                     IsXLHSInRHSPart = false;
10260                     IsPostfixUpdate = true;
10261                   } else {
10262                     ErrorFound = NotASpecificExpression;
10263                     ErrorLoc = FirstBinOp->getExprLoc();
10264                     ErrorRange = FirstBinOp->getSourceRange();
10265                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10266                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
10267                   }
10268                 }
10269               }
10270             }
10271           }
10272         } else {
10273           NoteLoc = ErrorLoc = Body->getBeginLoc();
10274           NoteRange = ErrorRange =
10275               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10276           ErrorFound = NotTwoSubstatements;
10277         }
10278       } else {
10279         NoteLoc = ErrorLoc = Body->getBeginLoc();
10280         NoteRange = ErrorRange =
10281             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10282         ErrorFound = NotACompoundStatement;
10283       }
10284       if (ErrorFound != NoError) {
10285         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10286             << ErrorRange;
10287         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10288         return StmtError();
10289       }
10290       if (CurContext->isDependentContext())
10291         UE = V = E = X = nullptr;
10292     }
10293   }
10294 
10295   setFunctionHasBranchProtectedScope();
10296 
10297   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10298                                     X, V, E, UE, IsXLHSInRHSPart,
10299                                     IsPostfixUpdate);
10300 }
10301 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10302 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10303                                             Stmt *AStmt,
10304                                             SourceLocation StartLoc,
10305                                             SourceLocation EndLoc) {
10306   if (!AStmt)
10307     return StmtError();
10308 
10309   auto *CS = cast<CapturedStmt>(AStmt);
10310   // 1.2.2 OpenMP Language Terminology
10311   // Structured block - An executable statement with a single entry at the
10312   // top and a single exit at the bottom.
10313   // The point of exit cannot be a branch out of the structured block.
10314   // longjmp() and throw() must not violate the entry/exit criteria.
10315   CS->getCapturedDecl()->setNothrow();
10316   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10317        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10318     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10319     // 1.2.2 OpenMP Language Terminology
10320     // Structured block - An executable statement with a single entry at the
10321     // top and a single exit at the bottom.
10322     // The point of exit cannot be a branch out of the structured block.
10323     // longjmp() and throw() must not violate the entry/exit criteria.
10324     CS->getCapturedDecl()->setNothrow();
10325   }
10326 
10327   // OpenMP [2.16, Nesting of Regions]
10328   // If specified, a teams construct must be contained within a target
10329   // construct. That target construct must contain no statements or directives
10330   // outside of the teams construct.
10331   if (DSAStack->hasInnerTeamsRegion()) {
10332     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10333     bool OMPTeamsFound = true;
10334     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10335       auto I = CS->body_begin();
10336       while (I != CS->body_end()) {
10337         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10338         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10339             OMPTeamsFound) {
10340 
10341           OMPTeamsFound = false;
10342           break;
10343         }
10344         ++I;
10345       }
10346       assert(I != CS->body_end() && "Not found statement");
10347       S = *I;
10348     } else {
10349       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10350       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10351     }
10352     if (!OMPTeamsFound) {
10353       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10354       Diag(DSAStack->getInnerTeamsRegionLoc(),
10355            diag::note_omp_nested_teams_construct_here);
10356       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10357           << isa<OMPExecutableDirective>(S);
10358       return StmtError();
10359     }
10360   }
10361 
10362   setFunctionHasBranchProtectedScope();
10363 
10364   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10365 }
10366 
10367 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10368 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10369                                          Stmt *AStmt, SourceLocation StartLoc,
10370                                          SourceLocation EndLoc) {
10371   if (!AStmt)
10372     return StmtError();
10373 
10374   auto *CS = cast<CapturedStmt>(AStmt);
10375   // 1.2.2 OpenMP Language Terminology
10376   // Structured block - An executable statement with a single entry at the
10377   // top and a single exit at the bottom.
10378   // The point of exit cannot be a branch out of the structured block.
10379   // longjmp() and throw() must not violate the entry/exit criteria.
10380   CS->getCapturedDecl()->setNothrow();
10381   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10382        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10383     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10384     // 1.2.2 OpenMP Language Terminology
10385     // Structured block - An executable statement with a single entry at the
10386     // top and a single exit at the bottom.
10387     // The point of exit cannot be a branch out of the structured block.
10388     // longjmp() and throw() must not violate the entry/exit criteria.
10389     CS->getCapturedDecl()->setNothrow();
10390   }
10391 
10392   setFunctionHasBranchProtectedScope();
10393 
10394   return OMPTargetParallelDirective::Create(
10395       Context, StartLoc, EndLoc, Clauses, AStmt,
10396       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10397 }
10398 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10399 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10400     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10401     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10402   if (!AStmt)
10403     return StmtError();
10404 
10405   auto *CS = cast<CapturedStmt>(AStmt);
10406   // 1.2.2 OpenMP Language Terminology
10407   // Structured block - An executable statement with a single entry at the
10408   // top and a single exit at the bottom.
10409   // The point of exit cannot be a branch out of the structured block.
10410   // longjmp() and throw() must not violate the entry/exit criteria.
10411   CS->getCapturedDecl()->setNothrow();
10412   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10413        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10414     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10415     // 1.2.2 OpenMP Language Terminology
10416     // Structured block - An executable statement with a single entry at the
10417     // top and a single exit at the bottom.
10418     // The point of exit cannot be a branch out of the structured block.
10419     // longjmp() and throw() must not violate the entry/exit criteria.
10420     CS->getCapturedDecl()->setNothrow();
10421   }
10422 
10423   OMPLoopDirective::HelperExprs B;
10424   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10425   // define the nested loops number.
10426   unsigned NestedLoopCount =
10427       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10428                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10429                       VarsWithImplicitDSA, B);
10430   if (NestedLoopCount == 0)
10431     return StmtError();
10432 
10433   assert((CurContext->isDependentContext() || B.builtAll()) &&
10434          "omp target parallel for loop exprs were not built");
10435 
10436   if (!CurContext->isDependentContext()) {
10437     // Finalize the clauses that need pre-built expressions for CodeGen.
10438     for (OMPClause *C : Clauses) {
10439       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10440         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10441                                      B.NumIterations, *this, CurScope,
10442                                      DSAStack))
10443           return StmtError();
10444     }
10445   }
10446 
10447   setFunctionHasBranchProtectedScope();
10448   return OMPTargetParallelForDirective::Create(
10449       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10450       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10451 }
10452 
10453 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)10454 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10455                        const OpenMPClauseKind K) {
10456   return llvm::any_of(
10457       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10458 }
10459 
10460 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)10461 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10462                        const Params... ClauseTypes) {
10463   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10464 }
10465 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10466 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10467                                                 Stmt *AStmt,
10468                                                 SourceLocation StartLoc,
10469                                                 SourceLocation EndLoc) {
10470   if (!AStmt)
10471     return StmtError();
10472 
10473   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10474 
10475   // OpenMP [2.12.2, target data Construct, Restrictions]
10476   // At least one map, use_device_addr or use_device_ptr clause must appear on
10477   // the directive.
10478   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10479       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10480     StringRef Expected;
10481     if (LangOpts.OpenMP < 50)
10482       Expected = "'map' or 'use_device_ptr'";
10483     else
10484       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10485     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10486         << Expected << getOpenMPDirectiveName(OMPD_target_data);
10487     return StmtError();
10488   }
10489 
10490   setFunctionHasBranchProtectedScope();
10491 
10492   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10493                                         AStmt);
10494 }
10495 
10496 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10497 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10498                                           SourceLocation StartLoc,
10499                                           SourceLocation EndLoc, Stmt *AStmt) {
10500   if (!AStmt)
10501     return StmtError();
10502 
10503   auto *CS = cast<CapturedStmt>(AStmt);
10504   // 1.2.2 OpenMP Language Terminology
10505   // Structured block - An executable statement with a single entry at the
10506   // top and a single exit at the bottom.
10507   // The point of exit cannot be a branch out of the structured block.
10508   // longjmp() and throw() must not violate the entry/exit criteria.
10509   CS->getCapturedDecl()->setNothrow();
10510   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10511        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10512     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10513     // 1.2.2 OpenMP Language Terminology
10514     // Structured block - An executable statement with a single entry at the
10515     // top and a single exit at the bottom.
10516     // The point of exit cannot be a branch out of the structured block.
10517     // longjmp() and throw() must not violate the entry/exit criteria.
10518     CS->getCapturedDecl()->setNothrow();
10519   }
10520 
10521   // OpenMP [2.10.2, Restrictions, p. 99]
10522   // At least one map clause must appear on the directive.
10523   if (!hasClauses(Clauses, OMPC_map)) {
10524     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10525         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10526     return StmtError();
10527   }
10528 
10529   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10530                                              AStmt);
10531 }
10532 
10533 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10534 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10535                                          SourceLocation StartLoc,
10536                                          SourceLocation EndLoc, Stmt *AStmt) {
10537   if (!AStmt)
10538     return StmtError();
10539 
10540   auto *CS = cast<CapturedStmt>(AStmt);
10541   // 1.2.2 OpenMP Language Terminology
10542   // Structured block - An executable statement with a single entry at the
10543   // top and a single exit at the bottom.
10544   // The point of exit cannot be a branch out of the structured block.
10545   // longjmp() and throw() must not violate the entry/exit criteria.
10546   CS->getCapturedDecl()->setNothrow();
10547   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10548        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10549     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10550     // 1.2.2 OpenMP Language Terminology
10551     // Structured block - An executable statement with a single entry at the
10552     // top and a single exit at the bottom.
10553     // The point of exit cannot be a branch out of the structured block.
10554     // longjmp() and throw() must not violate the entry/exit criteria.
10555     CS->getCapturedDecl()->setNothrow();
10556   }
10557 
10558   // OpenMP [2.10.3, Restrictions, p. 102]
10559   // At least one map clause must appear on the directive.
10560   if (!hasClauses(Clauses, OMPC_map)) {
10561     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10562         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10563     return StmtError();
10564   }
10565 
10566   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10567                                             AStmt);
10568 }
10569 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)10570 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10571                                                   SourceLocation StartLoc,
10572                                                   SourceLocation EndLoc,
10573                                                   Stmt *AStmt) {
10574   if (!AStmt)
10575     return StmtError();
10576 
10577   auto *CS = cast<CapturedStmt>(AStmt);
10578   // 1.2.2 OpenMP Language Terminology
10579   // Structured block - An executable statement with a single entry at the
10580   // top and a single exit at the bottom.
10581   // The point of exit cannot be a branch out of the structured block.
10582   // longjmp() and throw() must not violate the entry/exit criteria.
10583   CS->getCapturedDecl()->setNothrow();
10584   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10585        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10586     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10587     // 1.2.2 OpenMP Language Terminology
10588     // Structured block - An executable statement with a single entry at the
10589     // top and a single exit at the bottom.
10590     // The point of exit cannot be a branch out of the structured block.
10591     // longjmp() and throw() must not violate the entry/exit criteria.
10592     CS->getCapturedDecl()->setNothrow();
10593   }
10594 
10595   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10596     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10597     return StmtError();
10598   }
10599   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10600                                           AStmt);
10601 }
10602 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10603 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10604                                            Stmt *AStmt, SourceLocation StartLoc,
10605                                            SourceLocation EndLoc) {
10606   if (!AStmt)
10607     return StmtError();
10608 
10609   auto *CS = cast<CapturedStmt>(AStmt);
10610   // 1.2.2 OpenMP Language Terminology
10611   // Structured block - An executable statement with a single entry at the
10612   // top and a single exit at the bottom.
10613   // The point of exit cannot be a branch out of the structured block.
10614   // longjmp() and throw() must not violate the entry/exit criteria.
10615   CS->getCapturedDecl()->setNothrow();
10616 
10617   setFunctionHasBranchProtectedScope();
10618 
10619   DSAStack->setParentTeamsRegionLoc(StartLoc);
10620 
10621   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10622 }
10623 
10624 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)10625 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10626                                             SourceLocation EndLoc,
10627                                             OpenMPDirectiveKind CancelRegion) {
10628   if (DSAStack->isParentNowaitRegion()) {
10629     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10630     return StmtError();
10631   }
10632   if (DSAStack->isParentOrderedRegion()) {
10633     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10634     return StmtError();
10635   }
10636   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10637                                                CancelRegion);
10638 }
10639 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)10640 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10641                                             SourceLocation StartLoc,
10642                                             SourceLocation EndLoc,
10643                                             OpenMPDirectiveKind CancelRegion) {
10644   if (DSAStack->isParentNowaitRegion()) {
10645     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10646     return StmtError();
10647   }
10648   if (DSAStack->isParentOrderedRegion()) {
10649     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10650     return StmtError();
10651   }
10652   DSAStack->setParentCancelRegion(/*Cancel=*/true);
10653   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10654                                     CancelRegion);
10655 }
10656 
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)10657 static bool checkGrainsizeNumTasksClauses(Sema &S,
10658                                           ArrayRef<OMPClause *> Clauses) {
10659   const OMPClause *PrevClause = nullptr;
10660   bool ErrorFound = false;
10661   for (const OMPClause *C : Clauses) {
10662     if (C->getClauseKind() == OMPC_grainsize ||
10663         C->getClauseKind() == OMPC_num_tasks) {
10664       if (!PrevClause)
10665         PrevClause = C;
10666       else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10667         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10668             << getOpenMPClauseName(C->getClauseKind())
10669             << getOpenMPClauseName(PrevClause->getClauseKind());
10670         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10671             << getOpenMPClauseName(PrevClause->getClauseKind());
10672         ErrorFound = true;
10673       }
10674     }
10675   }
10676   return ErrorFound;
10677 }
10678 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)10679 static bool checkReductionClauseWithNogroup(Sema &S,
10680                                             ArrayRef<OMPClause *> Clauses) {
10681   const OMPClause *ReductionClause = nullptr;
10682   const OMPClause *NogroupClause = nullptr;
10683   for (const OMPClause *C : Clauses) {
10684     if (C->getClauseKind() == OMPC_reduction) {
10685       ReductionClause = C;
10686       if (NogroupClause)
10687         break;
10688       continue;
10689     }
10690     if (C->getClauseKind() == OMPC_nogroup) {
10691       NogroupClause = C;
10692       if (ReductionClause)
10693         break;
10694       continue;
10695     }
10696   }
10697   if (ReductionClause && NogroupClause) {
10698     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10699         << SourceRange(NogroupClause->getBeginLoc(),
10700                        NogroupClause->getEndLoc());
10701     return true;
10702   }
10703   return false;
10704 }
10705 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10706 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10707     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10708     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10709   if (!AStmt)
10710     return StmtError();
10711 
10712   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10713   OMPLoopDirective::HelperExprs B;
10714   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10715   // define the nested loops number.
10716   unsigned NestedLoopCount =
10717       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10718                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10719                       VarsWithImplicitDSA, B);
10720   if (NestedLoopCount == 0)
10721     return StmtError();
10722 
10723   assert((CurContext->isDependentContext() || B.builtAll()) &&
10724          "omp for loop exprs were not built");
10725 
10726   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10727   // The grainsize clause and num_tasks clause are mutually exclusive and may
10728   // not appear on the same taskloop directive.
10729   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10730     return StmtError();
10731   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10732   // If a reduction clause is present on the taskloop directive, the nogroup
10733   // clause must not be specified.
10734   if (checkReductionClauseWithNogroup(*this, Clauses))
10735     return StmtError();
10736 
10737   setFunctionHasBranchProtectedScope();
10738   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10739                                       NestedLoopCount, Clauses, AStmt, B,
10740                                       DSAStack->isCancelRegion());
10741 }
10742 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10743 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10744     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10745     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10746   if (!AStmt)
10747     return StmtError();
10748 
10749   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10750   OMPLoopDirective::HelperExprs B;
10751   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10752   // define the nested loops number.
10753   unsigned NestedLoopCount =
10754       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10755                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10756                       VarsWithImplicitDSA, B);
10757   if (NestedLoopCount == 0)
10758     return StmtError();
10759 
10760   assert((CurContext->isDependentContext() || B.builtAll()) &&
10761          "omp for loop exprs were not built");
10762 
10763   if (!CurContext->isDependentContext()) {
10764     // Finalize the clauses that need pre-built expressions for CodeGen.
10765     for (OMPClause *C : Clauses) {
10766       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10767         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10768                                      B.NumIterations, *this, CurScope,
10769                                      DSAStack))
10770           return StmtError();
10771     }
10772   }
10773 
10774   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10775   // The grainsize clause and num_tasks clause are mutually exclusive and may
10776   // not appear on the same taskloop directive.
10777   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10778     return StmtError();
10779   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10780   // If a reduction clause is present on the taskloop directive, the nogroup
10781   // clause must not be specified.
10782   if (checkReductionClauseWithNogroup(*this, Clauses))
10783     return StmtError();
10784   if (checkSimdlenSafelenSpecified(*this, Clauses))
10785     return StmtError();
10786 
10787   setFunctionHasBranchProtectedScope();
10788   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10789                                           NestedLoopCount, Clauses, AStmt, B);
10790 }
10791 
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10792 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10793     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10794     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10795   if (!AStmt)
10796     return StmtError();
10797 
10798   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10799   OMPLoopDirective::HelperExprs B;
10800   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10801   // define the nested loops number.
10802   unsigned NestedLoopCount =
10803       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10804                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10805                       VarsWithImplicitDSA, B);
10806   if (NestedLoopCount == 0)
10807     return StmtError();
10808 
10809   assert((CurContext->isDependentContext() || B.builtAll()) &&
10810          "omp for loop exprs were not built");
10811 
10812   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10813   // The grainsize clause and num_tasks clause are mutually exclusive and may
10814   // not appear on the same taskloop directive.
10815   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10816     return StmtError();
10817   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10818   // If a reduction clause is present on the taskloop directive, the nogroup
10819   // clause must not be specified.
10820   if (checkReductionClauseWithNogroup(*this, Clauses))
10821     return StmtError();
10822 
10823   setFunctionHasBranchProtectedScope();
10824   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10825                                             NestedLoopCount, Clauses, AStmt, B,
10826                                             DSAStack->isCancelRegion());
10827 }
10828 
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10829 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10830     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10831     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10832   if (!AStmt)
10833     return StmtError();
10834 
10835   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10836   OMPLoopDirective::HelperExprs B;
10837   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10838   // define the nested loops number.
10839   unsigned NestedLoopCount =
10840       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10841                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10842                       VarsWithImplicitDSA, B);
10843   if (NestedLoopCount == 0)
10844     return StmtError();
10845 
10846   assert((CurContext->isDependentContext() || B.builtAll()) &&
10847          "omp for loop exprs were not built");
10848 
10849   if (!CurContext->isDependentContext()) {
10850     // Finalize the clauses that need pre-built expressions for CodeGen.
10851     for (OMPClause *C : Clauses) {
10852       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10853         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10854                                      B.NumIterations, *this, CurScope,
10855                                      DSAStack))
10856           return StmtError();
10857     }
10858   }
10859 
10860   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10861   // The grainsize clause and num_tasks clause are mutually exclusive and may
10862   // not appear on the same taskloop directive.
10863   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10864     return StmtError();
10865   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10866   // If a reduction clause is present on the taskloop directive, the nogroup
10867   // clause must not be specified.
10868   if (checkReductionClauseWithNogroup(*this, Clauses))
10869     return StmtError();
10870   if (checkSimdlenSafelenSpecified(*this, Clauses))
10871     return StmtError();
10872 
10873   setFunctionHasBranchProtectedScope();
10874   return OMPMasterTaskLoopSimdDirective::Create(
10875       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10876 }
10877 
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10878 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10879     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10880     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10881   if (!AStmt)
10882     return StmtError();
10883 
10884   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10885   auto *CS = cast<CapturedStmt>(AStmt);
10886   // 1.2.2 OpenMP Language Terminology
10887   // Structured block - An executable statement with a single entry at the
10888   // top and a single exit at the bottom.
10889   // The point of exit cannot be a branch out of the structured block.
10890   // longjmp() and throw() must not violate the entry/exit criteria.
10891   CS->getCapturedDecl()->setNothrow();
10892   for (int ThisCaptureLevel =
10893            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10894        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10895     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10896     // 1.2.2 OpenMP Language Terminology
10897     // Structured block - An executable statement with a single entry at the
10898     // top and a single exit at the bottom.
10899     // The point of exit cannot be a branch out of the structured block.
10900     // longjmp() and throw() must not violate the entry/exit criteria.
10901     CS->getCapturedDecl()->setNothrow();
10902   }
10903 
10904   OMPLoopDirective::HelperExprs B;
10905   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10906   // define the nested loops number.
10907   unsigned NestedLoopCount = checkOpenMPLoop(
10908       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10909       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10910       VarsWithImplicitDSA, B);
10911   if (NestedLoopCount == 0)
10912     return StmtError();
10913 
10914   assert((CurContext->isDependentContext() || B.builtAll()) &&
10915          "omp for loop exprs were not built");
10916 
10917   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10918   // The grainsize clause and num_tasks clause are mutually exclusive and may
10919   // not appear on the same taskloop directive.
10920   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10921     return StmtError();
10922   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10923   // If a reduction clause is present on the taskloop directive, the nogroup
10924   // clause must not be specified.
10925   if (checkReductionClauseWithNogroup(*this, Clauses))
10926     return StmtError();
10927 
10928   setFunctionHasBranchProtectedScope();
10929   return OMPParallelMasterTaskLoopDirective::Create(
10930       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10931       DSAStack->isCancelRegion());
10932 }
10933 
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10934 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10935     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10936     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10937   if (!AStmt)
10938     return StmtError();
10939 
10940   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10941   auto *CS = cast<CapturedStmt>(AStmt);
10942   // 1.2.2 OpenMP Language Terminology
10943   // Structured block - An executable statement with a single entry at the
10944   // top and a single exit at the bottom.
10945   // The point of exit cannot be a branch out of the structured block.
10946   // longjmp() and throw() must not violate the entry/exit criteria.
10947   CS->getCapturedDecl()->setNothrow();
10948   for (int ThisCaptureLevel =
10949            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10950        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10951     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10952     // 1.2.2 OpenMP Language Terminology
10953     // Structured block - An executable statement with a single entry at the
10954     // top and a single exit at the bottom.
10955     // The point of exit cannot be a branch out of the structured block.
10956     // longjmp() and throw() must not violate the entry/exit criteria.
10957     CS->getCapturedDecl()->setNothrow();
10958   }
10959 
10960   OMPLoopDirective::HelperExprs B;
10961   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10962   // define the nested loops number.
10963   unsigned NestedLoopCount = checkOpenMPLoop(
10964       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10965       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10966       VarsWithImplicitDSA, B);
10967   if (NestedLoopCount == 0)
10968     return StmtError();
10969 
10970   assert((CurContext->isDependentContext() || B.builtAll()) &&
10971          "omp for loop exprs were not built");
10972 
10973   if (!CurContext->isDependentContext()) {
10974     // Finalize the clauses that need pre-built expressions for CodeGen.
10975     for (OMPClause *C : Clauses) {
10976       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10977         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10978                                      B.NumIterations, *this, CurScope,
10979                                      DSAStack))
10980           return StmtError();
10981     }
10982   }
10983 
10984   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10985   // The grainsize clause and num_tasks clause are mutually exclusive and may
10986   // not appear on the same taskloop directive.
10987   if (checkGrainsizeNumTasksClauses(*this, Clauses))
10988     return StmtError();
10989   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10990   // If a reduction clause is present on the taskloop directive, the nogroup
10991   // clause must not be specified.
10992   if (checkReductionClauseWithNogroup(*this, Clauses))
10993     return StmtError();
10994   if (checkSimdlenSafelenSpecified(*this, Clauses))
10995     return StmtError();
10996 
10997   setFunctionHasBranchProtectedScope();
10998   return OMPParallelMasterTaskLoopSimdDirective::Create(
10999       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11000 }
11001 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11002 StmtResult Sema::ActOnOpenMPDistributeDirective(
11003     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11004     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11005   if (!AStmt)
11006     return StmtError();
11007 
11008   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11009   OMPLoopDirective::HelperExprs B;
11010   // In presence of clause 'collapse' with number of loops, it will
11011   // define the nested loops number.
11012   unsigned NestedLoopCount =
11013       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11014                       nullptr /*ordered not a clause on distribute*/, AStmt,
11015                       *this, *DSAStack, VarsWithImplicitDSA, B);
11016   if (NestedLoopCount == 0)
11017     return StmtError();
11018 
11019   assert((CurContext->isDependentContext() || B.builtAll()) &&
11020          "omp for loop exprs were not built");
11021 
11022   setFunctionHasBranchProtectedScope();
11023   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11024                                         NestedLoopCount, Clauses, AStmt, B);
11025 }
11026 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11027 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11028     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11029     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11030   if (!AStmt)
11031     return StmtError();
11032 
11033   auto *CS = cast<CapturedStmt>(AStmt);
11034   // 1.2.2 OpenMP Language Terminology
11035   // Structured block - An executable statement with a single entry at the
11036   // top and a single exit at the bottom.
11037   // The point of exit cannot be a branch out of the structured block.
11038   // longjmp() and throw() must not violate the entry/exit criteria.
11039   CS->getCapturedDecl()->setNothrow();
11040   for (int ThisCaptureLevel =
11041            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11042        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11043     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11044     // 1.2.2 OpenMP Language Terminology
11045     // Structured block - An executable statement with a single entry at the
11046     // top and a single exit at the bottom.
11047     // The point of exit cannot be a branch out of the structured block.
11048     // longjmp() and throw() must not violate the entry/exit criteria.
11049     CS->getCapturedDecl()->setNothrow();
11050   }
11051 
11052   OMPLoopDirective::HelperExprs B;
11053   // In presence of clause 'collapse' with number of loops, it will
11054   // define the nested loops number.
11055   unsigned NestedLoopCount = checkOpenMPLoop(
11056       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11057       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11058       VarsWithImplicitDSA, B);
11059   if (NestedLoopCount == 0)
11060     return StmtError();
11061 
11062   assert((CurContext->isDependentContext() || B.builtAll()) &&
11063          "omp for loop exprs were not built");
11064 
11065   setFunctionHasBranchProtectedScope();
11066   return OMPDistributeParallelForDirective::Create(
11067       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11068       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11069 }
11070 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11071 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11072     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11073     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11074   if (!AStmt)
11075     return StmtError();
11076 
11077   auto *CS = cast<CapturedStmt>(AStmt);
11078   // 1.2.2 OpenMP Language Terminology
11079   // Structured block - An executable statement with a single entry at the
11080   // top and a single exit at the bottom.
11081   // The point of exit cannot be a branch out of the structured block.
11082   // longjmp() and throw() must not violate the entry/exit criteria.
11083   CS->getCapturedDecl()->setNothrow();
11084   for (int ThisCaptureLevel =
11085            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11086        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11087     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11088     // 1.2.2 OpenMP Language Terminology
11089     // Structured block - An executable statement with a single entry at the
11090     // top and a single exit at the bottom.
11091     // The point of exit cannot be a branch out of the structured block.
11092     // longjmp() and throw() must not violate the entry/exit criteria.
11093     CS->getCapturedDecl()->setNothrow();
11094   }
11095 
11096   OMPLoopDirective::HelperExprs B;
11097   // In presence of clause 'collapse' with number of loops, it will
11098   // define the nested loops number.
11099   unsigned NestedLoopCount = checkOpenMPLoop(
11100       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11101       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11102       VarsWithImplicitDSA, B);
11103   if (NestedLoopCount == 0)
11104     return StmtError();
11105 
11106   assert((CurContext->isDependentContext() || B.builtAll()) &&
11107          "omp for loop exprs were not built");
11108 
11109   if (!CurContext->isDependentContext()) {
11110     // Finalize the clauses that need pre-built expressions for CodeGen.
11111     for (OMPClause *C : Clauses) {
11112       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11113         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11114                                      B.NumIterations, *this, CurScope,
11115                                      DSAStack))
11116           return StmtError();
11117     }
11118   }
11119 
11120   if (checkSimdlenSafelenSpecified(*this, Clauses))
11121     return StmtError();
11122 
11123   setFunctionHasBranchProtectedScope();
11124   return OMPDistributeParallelForSimdDirective::Create(
11125       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11126 }
11127 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11128 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11129     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11130     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11131   if (!AStmt)
11132     return StmtError();
11133 
11134   auto *CS = cast<CapturedStmt>(AStmt);
11135   // 1.2.2 OpenMP Language Terminology
11136   // Structured block - An executable statement with a single entry at the
11137   // top and a single exit at the bottom.
11138   // The point of exit cannot be a branch out of the structured block.
11139   // longjmp() and throw() must not violate the entry/exit criteria.
11140   CS->getCapturedDecl()->setNothrow();
11141   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11142        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11143     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11144     // 1.2.2 OpenMP Language Terminology
11145     // Structured block - An executable statement with a single entry at the
11146     // top and a single exit at the bottom.
11147     // The point of exit cannot be a branch out of the structured block.
11148     // longjmp() and throw() must not violate the entry/exit criteria.
11149     CS->getCapturedDecl()->setNothrow();
11150   }
11151 
11152   OMPLoopDirective::HelperExprs B;
11153   // In presence of clause 'collapse' with number of loops, it will
11154   // define the nested loops number.
11155   unsigned NestedLoopCount =
11156       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11157                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11158                       *DSAStack, VarsWithImplicitDSA, B);
11159   if (NestedLoopCount == 0)
11160     return StmtError();
11161 
11162   assert((CurContext->isDependentContext() || B.builtAll()) &&
11163          "omp for loop exprs were not built");
11164 
11165   if (!CurContext->isDependentContext()) {
11166     // Finalize the clauses that need pre-built expressions for CodeGen.
11167     for (OMPClause *C : Clauses) {
11168       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11169         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11170                                      B.NumIterations, *this, CurScope,
11171                                      DSAStack))
11172           return StmtError();
11173     }
11174   }
11175 
11176   if (checkSimdlenSafelenSpecified(*this, Clauses))
11177     return StmtError();
11178 
11179   setFunctionHasBranchProtectedScope();
11180   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11181                                             NestedLoopCount, Clauses, AStmt, B);
11182 }
11183 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11184 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11185     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11186     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11187   if (!AStmt)
11188     return StmtError();
11189 
11190   auto *CS = cast<CapturedStmt>(AStmt);
11191   // 1.2.2 OpenMP Language Terminology
11192   // Structured block - An executable statement with a single entry at the
11193   // top and a single exit at the bottom.
11194   // The point of exit cannot be a branch out of the structured block.
11195   // longjmp() and throw() must not violate the entry/exit criteria.
11196   CS->getCapturedDecl()->setNothrow();
11197   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11198        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11199     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11200     // 1.2.2 OpenMP Language Terminology
11201     // Structured block - An executable statement with a single entry at the
11202     // top and a single exit at the bottom.
11203     // The point of exit cannot be a branch out of the structured block.
11204     // longjmp() and throw() must not violate the entry/exit criteria.
11205     CS->getCapturedDecl()->setNothrow();
11206   }
11207 
11208   OMPLoopDirective::HelperExprs B;
11209   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11210   // define the nested loops number.
11211   unsigned NestedLoopCount = checkOpenMPLoop(
11212       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11213       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11214       VarsWithImplicitDSA, B);
11215   if (NestedLoopCount == 0)
11216     return StmtError();
11217 
11218   assert((CurContext->isDependentContext() || B.builtAll()) &&
11219          "omp target parallel for simd loop exprs were not built");
11220 
11221   if (!CurContext->isDependentContext()) {
11222     // Finalize the clauses that need pre-built expressions for CodeGen.
11223     for (OMPClause *C : Clauses) {
11224       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11225         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11226                                      B.NumIterations, *this, CurScope,
11227                                      DSAStack))
11228           return StmtError();
11229     }
11230   }
11231   if (checkSimdlenSafelenSpecified(*this, Clauses))
11232     return StmtError();
11233 
11234   setFunctionHasBranchProtectedScope();
11235   return OMPTargetParallelForSimdDirective::Create(
11236       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11237 }
11238 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11239 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11240     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11241     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11242   if (!AStmt)
11243     return StmtError();
11244 
11245   auto *CS = cast<CapturedStmt>(AStmt);
11246   // 1.2.2 OpenMP Language Terminology
11247   // Structured block - An executable statement with a single entry at the
11248   // top and a single exit at the bottom.
11249   // The point of exit cannot be a branch out of the structured block.
11250   // longjmp() and throw() must not violate the entry/exit criteria.
11251   CS->getCapturedDecl()->setNothrow();
11252   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11253        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11254     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11255     // 1.2.2 OpenMP Language Terminology
11256     // Structured block - An executable statement with a single entry at the
11257     // top and a single exit at the bottom.
11258     // The point of exit cannot be a branch out of the structured block.
11259     // longjmp() and throw() must not violate the entry/exit criteria.
11260     CS->getCapturedDecl()->setNothrow();
11261   }
11262 
11263   OMPLoopDirective::HelperExprs B;
11264   // In presence of clause 'collapse' with number of loops, it will define the
11265   // nested loops number.
11266   unsigned NestedLoopCount =
11267       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11268                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11269                       VarsWithImplicitDSA, B);
11270   if (NestedLoopCount == 0)
11271     return StmtError();
11272 
11273   assert((CurContext->isDependentContext() || B.builtAll()) &&
11274          "omp target simd loop exprs were not built");
11275 
11276   if (!CurContext->isDependentContext()) {
11277     // Finalize the clauses that need pre-built expressions for CodeGen.
11278     for (OMPClause *C : Clauses) {
11279       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11280         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11281                                      B.NumIterations, *this, CurScope,
11282                                      DSAStack))
11283           return StmtError();
11284     }
11285   }
11286 
11287   if (checkSimdlenSafelenSpecified(*this, Clauses))
11288     return StmtError();
11289 
11290   setFunctionHasBranchProtectedScope();
11291   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11292                                         NestedLoopCount, Clauses, AStmt, B);
11293 }
11294 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11295 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11296     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11297     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11298   if (!AStmt)
11299     return StmtError();
11300 
11301   auto *CS = cast<CapturedStmt>(AStmt);
11302   // 1.2.2 OpenMP Language Terminology
11303   // Structured block - An executable statement with a single entry at the
11304   // top and a single exit at the bottom.
11305   // The point of exit cannot be a branch out of the structured block.
11306   // longjmp() and throw() must not violate the entry/exit criteria.
11307   CS->getCapturedDecl()->setNothrow();
11308   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11309        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11310     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11311     // 1.2.2 OpenMP Language Terminology
11312     // Structured block - An executable statement with a single entry at the
11313     // top and a single exit at the bottom.
11314     // The point of exit cannot be a branch out of the structured block.
11315     // longjmp() and throw() must not violate the entry/exit criteria.
11316     CS->getCapturedDecl()->setNothrow();
11317   }
11318 
11319   OMPLoopDirective::HelperExprs B;
11320   // In presence of clause 'collapse' with number of loops, it will
11321   // define the nested loops number.
11322   unsigned NestedLoopCount =
11323       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11324                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11325                       *DSAStack, VarsWithImplicitDSA, B);
11326   if (NestedLoopCount == 0)
11327     return StmtError();
11328 
11329   assert((CurContext->isDependentContext() || B.builtAll()) &&
11330          "omp teams distribute loop exprs were not built");
11331 
11332   setFunctionHasBranchProtectedScope();
11333 
11334   DSAStack->setParentTeamsRegionLoc(StartLoc);
11335 
11336   return OMPTeamsDistributeDirective::Create(
11337       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11338 }
11339 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11340 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11341     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11342     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11343   if (!AStmt)
11344     return StmtError();
11345 
11346   auto *CS = cast<CapturedStmt>(AStmt);
11347   // 1.2.2 OpenMP Language Terminology
11348   // Structured block - An executable statement with a single entry at the
11349   // top and a single exit at the bottom.
11350   // The point of exit cannot be a branch out of the structured block.
11351   // longjmp() and throw() must not violate the entry/exit criteria.
11352   CS->getCapturedDecl()->setNothrow();
11353   for (int ThisCaptureLevel =
11354            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11355        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11356     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11357     // 1.2.2 OpenMP Language Terminology
11358     // Structured block - An executable statement with a single entry at the
11359     // top and a single exit at the bottom.
11360     // The point of exit cannot be a branch out of the structured block.
11361     // longjmp() and throw() must not violate the entry/exit criteria.
11362     CS->getCapturedDecl()->setNothrow();
11363   }
11364 
11365   OMPLoopDirective::HelperExprs B;
11366   // In presence of clause 'collapse' with number of loops, it will
11367   // define the nested loops number.
11368   unsigned NestedLoopCount = checkOpenMPLoop(
11369       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11370       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11371       VarsWithImplicitDSA, B);
11372 
11373   if (NestedLoopCount == 0)
11374     return StmtError();
11375 
11376   assert((CurContext->isDependentContext() || B.builtAll()) &&
11377          "omp teams distribute simd loop exprs were not built");
11378 
11379   if (!CurContext->isDependentContext()) {
11380     // Finalize the clauses that need pre-built expressions for CodeGen.
11381     for (OMPClause *C : Clauses) {
11382       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11383         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11384                                      B.NumIterations, *this, CurScope,
11385                                      DSAStack))
11386           return StmtError();
11387     }
11388   }
11389 
11390   if (checkSimdlenSafelenSpecified(*this, Clauses))
11391     return StmtError();
11392 
11393   setFunctionHasBranchProtectedScope();
11394 
11395   DSAStack->setParentTeamsRegionLoc(StartLoc);
11396 
11397   return OMPTeamsDistributeSimdDirective::Create(
11398       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11399 }
11400 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11401 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11402     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11403     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11404   if (!AStmt)
11405     return StmtError();
11406 
11407   auto *CS = cast<CapturedStmt>(AStmt);
11408   // 1.2.2 OpenMP Language Terminology
11409   // Structured block - An executable statement with a single entry at the
11410   // top and a single exit at the bottom.
11411   // The point of exit cannot be a branch out of the structured block.
11412   // longjmp() and throw() must not violate the entry/exit criteria.
11413   CS->getCapturedDecl()->setNothrow();
11414 
11415   for (int ThisCaptureLevel =
11416            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11417        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11418     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11419     // 1.2.2 OpenMP Language Terminology
11420     // Structured block - An executable statement with a single entry at the
11421     // top and a single exit at the bottom.
11422     // The point of exit cannot be a branch out of the structured block.
11423     // longjmp() and throw() must not violate the entry/exit criteria.
11424     CS->getCapturedDecl()->setNothrow();
11425   }
11426 
11427   OMPLoopDirective::HelperExprs B;
11428   // In presence of clause 'collapse' with number of loops, it will
11429   // define the nested loops number.
11430   unsigned NestedLoopCount = checkOpenMPLoop(
11431       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11432       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11433       VarsWithImplicitDSA, B);
11434 
11435   if (NestedLoopCount == 0)
11436     return StmtError();
11437 
11438   assert((CurContext->isDependentContext() || B.builtAll()) &&
11439          "omp for loop exprs were not built");
11440 
11441   if (!CurContext->isDependentContext()) {
11442     // Finalize the clauses that need pre-built expressions for CodeGen.
11443     for (OMPClause *C : Clauses) {
11444       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11445         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11446                                      B.NumIterations, *this, CurScope,
11447                                      DSAStack))
11448           return StmtError();
11449     }
11450   }
11451 
11452   if (checkSimdlenSafelenSpecified(*this, Clauses))
11453     return StmtError();
11454 
11455   setFunctionHasBranchProtectedScope();
11456 
11457   DSAStack->setParentTeamsRegionLoc(StartLoc);
11458 
11459   return OMPTeamsDistributeParallelForSimdDirective::Create(
11460       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11461 }
11462 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11463 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11464     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11465     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11466   if (!AStmt)
11467     return StmtError();
11468 
11469   auto *CS = cast<CapturedStmt>(AStmt);
11470   // 1.2.2 OpenMP Language Terminology
11471   // Structured block - An executable statement with a single entry at the
11472   // top and a single exit at the bottom.
11473   // The point of exit cannot be a branch out of the structured block.
11474   // longjmp() and throw() must not violate the entry/exit criteria.
11475   CS->getCapturedDecl()->setNothrow();
11476 
11477   for (int ThisCaptureLevel =
11478            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11479        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11480     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11481     // 1.2.2 OpenMP Language Terminology
11482     // Structured block - An executable statement with a single entry at the
11483     // top and a single exit at the bottom.
11484     // The point of exit cannot be a branch out of the structured block.
11485     // longjmp() and throw() must not violate the entry/exit criteria.
11486     CS->getCapturedDecl()->setNothrow();
11487   }
11488 
11489   OMPLoopDirective::HelperExprs B;
11490   // In presence of clause 'collapse' with number of loops, it will
11491   // define the nested loops number.
11492   unsigned NestedLoopCount = checkOpenMPLoop(
11493       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11494       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11495       VarsWithImplicitDSA, B);
11496 
11497   if (NestedLoopCount == 0)
11498     return StmtError();
11499 
11500   assert((CurContext->isDependentContext() || B.builtAll()) &&
11501          "omp for loop exprs were not built");
11502 
11503   setFunctionHasBranchProtectedScope();
11504 
11505   DSAStack->setParentTeamsRegionLoc(StartLoc);
11506 
11507   return OMPTeamsDistributeParallelForDirective::Create(
11508       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11509       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11510 }
11511 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11512 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11513                                                  Stmt *AStmt,
11514                                                  SourceLocation StartLoc,
11515                                                  SourceLocation EndLoc) {
11516   if (!AStmt)
11517     return StmtError();
11518 
11519   auto *CS = cast<CapturedStmt>(AStmt);
11520   // 1.2.2 OpenMP Language Terminology
11521   // Structured block - An executable statement with a single entry at the
11522   // top and a single exit at the bottom.
11523   // The point of exit cannot be a branch out of the structured block.
11524   // longjmp() and throw() must not violate the entry/exit criteria.
11525   CS->getCapturedDecl()->setNothrow();
11526 
11527   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11528        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11529     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11530     // 1.2.2 OpenMP Language Terminology
11531     // Structured block - An executable statement with a single entry at the
11532     // top and a single exit at the bottom.
11533     // The point of exit cannot be a branch out of the structured block.
11534     // longjmp() and throw() must not violate the entry/exit criteria.
11535     CS->getCapturedDecl()->setNothrow();
11536   }
11537   setFunctionHasBranchProtectedScope();
11538 
11539   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11540                                          AStmt);
11541 }
11542 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11543 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11544     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11545     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11546   if (!AStmt)
11547     return StmtError();
11548 
11549   auto *CS = cast<CapturedStmt>(AStmt);
11550   // 1.2.2 OpenMP Language Terminology
11551   // Structured block - An executable statement with a single entry at the
11552   // top and a single exit at the bottom.
11553   // The point of exit cannot be a branch out of the structured block.
11554   // longjmp() and throw() must not violate the entry/exit criteria.
11555   CS->getCapturedDecl()->setNothrow();
11556   for (int ThisCaptureLevel =
11557            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11558        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11559     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11560     // 1.2.2 OpenMP Language Terminology
11561     // Structured block - An executable statement with a single entry at the
11562     // top and a single exit at the bottom.
11563     // The point of exit cannot be a branch out of the structured block.
11564     // longjmp() and throw() must not violate the entry/exit criteria.
11565     CS->getCapturedDecl()->setNothrow();
11566   }
11567 
11568   OMPLoopDirective::HelperExprs B;
11569   // In presence of clause 'collapse' with number of loops, it will
11570   // define the nested loops number.
11571   unsigned NestedLoopCount = checkOpenMPLoop(
11572       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11573       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11574       VarsWithImplicitDSA, B);
11575   if (NestedLoopCount == 0)
11576     return StmtError();
11577 
11578   assert((CurContext->isDependentContext() || B.builtAll()) &&
11579          "omp target teams distribute loop exprs were not built");
11580 
11581   setFunctionHasBranchProtectedScope();
11582   return OMPTargetTeamsDistributeDirective::Create(
11583       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11584 }
11585 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11586 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11587     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11588     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11589   if (!AStmt)
11590     return StmtError();
11591 
11592   auto *CS = cast<CapturedStmt>(AStmt);
11593   // 1.2.2 OpenMP Language Terminology
11594   // Structured block - An executable statement with a single entry at the
11595   // top and a single exit at the bottom.
11596   // The point of exit cannot be a branch out of the structured block.
11597   // longjmp() and throw() must not violate the entry/exit criteria.
11598   CS->getCapturedDecl()->setNothrow();
11599   for (int ThisCaptureLevel =
11600            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11601        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11602     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11603     // 1.2.2 OpenMP Language Terminology
11604     // Structured block - An executable statement with a single entry at the
11605     // top and a single exit at the bottom.
11606     // The point of exit cannot be a branch out of the structured block.
11607     // longjmp() and throw() must not violate the entry/exit criteria.
11608     CS->getCapturedDecl()->setNothrow();
11609   }
11610 
11611   OMPLoopDirective::HelperExprs B;
11612   // In presence of clause 'collapse' with number of loops, it will
11613   // define the nested loops number.
11614   unsigned NestedLoopCount = checkOpenMPLoop(
11615       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11616       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11617       VarsWithImplicitDSA, B);
11618   if (NestedLoopCount == 0)
11619     return StmtError();
11620 
11621   assert((CurContext->isDependentContext() || B.builtAll()) &&
11622          "omp target teams distribute parallel for loop exprs were not built");
11623 
11624   if (!CurContext->isDependentContext()) {
11625     // Finalize the clauses that need pre-built expressions for CodeGen.
11626     for (OMPClause *C : Clauses) {
11627       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11628         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11629                                      B.NumIterations, *this, CurScope,
11630                                      DSAStack))
11631           return StmtError();
11632     }
11633   }
11634 
11635   setFunctionHasBranchProtectedScope();
11636   return OMPTargetTeamsDistributeParallelForDirective::Create(
11637       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11638       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11639 }
11640 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11641 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11642     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11643     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11644   if (!AStmt)
11645     return StmtError();
11646 
11647   auto *CS = cast<CapturedStmt>(AStmt);
11648   // 1.2.2 OpenMP Language Terminology
11649   // Structured block - An executable statement with a single entry at the
11650   // top and a single exit at the bottom.
11651   // The point of exit cannot be a branch out of the structured block.
11652   // longjmp() and throw() must not violate the entry/exit criteria.
11653   CS->getCapturedDecl()->setNothrow();
11654   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11655            OMPD_target_teams_distribute_parallel_for_simd);
11656        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11657     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11658     // 1.2.2 OpenMP Language Terminology
11659     // Structured block - An executable statement with a single entry at the
11660     // top and a single exit at the bottom.
11661     // The point of exit cannot be a branch out of the structured block.
11662     // longjmp() and throw() must not violate the entry/exit criteria.
11663     CS->getCapturedDecl()->setNothrow();
11664   }
11665 
11666   OMPLoopDirective::HelperExprs B;
11667   // In presence of clause 'collapse' with number of loops, it will
11668   // define the nested loops number.
11669   unsigned NestedLoopCount =
11670       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11671                       getCollapseNumberExpr(Clauses),
11672                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11673                       *DSAStack, VarsWithImplicitDSA, B);
11674   if (NestedLoopCount == 0)
11675     return StmtError();
11676 
11677   assert((CurContext->isDependentContext() || B.builtAll()) &&
11678          "omp target teams distribute parallel for simd loop exprs were not "
11679          "built");
11680 
11681   if (!CurContext->isDependentContext()) {
11682     // Finalize the clauses that need pre-built expressions for CodeGen.
11683     for (OMPClause *C : Clauses) {
11684       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11685         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11686                                      B.NumIterations, *this, CurScope,
11687                                      DSAStack))
11688           return StmtError();
11689     }
11690   }
11691 
11692   if (checkSimdlenSafelenSpecified(*this, Clauses))
11693     return StmtError();
11694 
11695   setFunctionHasBranchProtectedScope();
11696   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11697       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11698 }
11699 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11700 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11701     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11702     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11703   if (!AStmt)
11704     return StmtError();
11705 
11706   auto *CS = cast<CapturedStmt>(AStmt);
11707   // 1.2.2 OpenMP Language Terminology
11708   // Structured block - An executable statement with a single entry at the
11709   // top and a single exit at the bottom.
11710   // The point of exit cannot be a branch out of the structured block.
11711   // longjmp() and throw() must not violate the entry/exit criteria.
11712   CS->getCapturedDecl()->setNothrow();
11713   for (int ThisCaptureLevel =
11714            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11715        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11716     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11717     // 1.2.2 OpenMP Language Terminology
11718     // Structured block - An executable statement with a single entry at the
11719     // top and a single exit at the bottom.
11720     // The point of exit cannot be a branch out of the structured block.
11721     // longjmp() and throw() must not violate the entry/exit criteria.
11722     CS->getCapturedDecl()->setNothrow();
11723   }
11724 
11725   OMPLoopDirective::HelperExprs B;
11726   // In presence of clause 'collapse' with number of loops, it will
11727   // define the nested loops number.
11728   unsigned NestedLoopCount = checkOpenMPLoop(
11729       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11730       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11731       VarsWithImplicitDSA, B);
11732   if (NestedLoopCount == 0)
11733     return StmtError();
11734 
11735   assert((CurContext->isDependentContext() || B.builtAll()) &&
11736          "omp target teams distribute simd loop exprs were not built");
11737 
11738   if (!CurContext->isDependentContext()) {
11739     // Finalize the clauses that need pre-built expressions for CodeGen.
11740     for (OMPClause *C : Clauses) {
11741       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11742         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11743                                      B.NumIterations, *this, CurScope,
11744                                      DSAStack))
11745           return StmtError();
11746     }
11747   }
11748 
11749   if (checkSimdlenSafelenSpecified(*this, Clauses))
11750     return StmtError();
11751 
11752   setFunctionHasBranchProtectedScope();
11753   return OMPTargetTeamsDistributeSimdDirective::Create(
11754       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11755 }
11756 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11757 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11758                                              SourceLocation StartLoc,
11759                                              SourceLocation LParenLoc,
11760                                              SourceLocation EndLoc) {
11761   OMPClause *Res = nullptr;
11762   switch (Kind) {
11763   case OMPC_final:
11764     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11765     break;
11766   case OMPC_num_threads:
11767     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11768     break;
11769   case OMPC_safelen:
11770     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11771     break;
11772   case OMPC_simdlen:
11773     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11774     break;
11775   case OMPC_allocator:
11776     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11777     break;
11778   case OMPC_collapse:
11779     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11780     break;
11781   case OMPC_ordered:
11782     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11783     break;
11784   case OMPC_num_teams:
11785     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11786     break;
11787   case OMPC_thread_limit:
11788     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11789     break;
11790   case OMPC_priority:
11791     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11792     break;
11793   case OMPC_grainsize:
11794     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11795     break;
11796   case OMPC_num_tasks:
11797     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11798     break;
11799   case OMPC_hint:
11800     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11801     break;
11802   case OMPC_depobj:
11803     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11804     break;
11805   case OMPC_detach:
11806     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11807     break;
11808   case OMPC_device:
11809   case OMPC_if:
11810   case OMPC_default:
11811   case OMPC_proc_bind:
11812   case OMPC_schedule:
11813   case OMPC_private:
11814   case OMPC_firstprivate:
11815   case OMPC_lastprivate:
11816   case OMPC_shared:
11817   case OMPC_reduction:
11818   case OMPC_task_reduction:
11819   case OMPC_in_reduction:
11820   case OMPC_linear:
11821   case OMPC_aligned:
11822   case OMPC_copyin:
11823   case OMPC_copyprivate:
11824   case OMPC_nowait:
11825   case OMPC_untied:
11826   case OMPC_mergeable:
11827   case OMPC_threadprivate:
11828   case OMPC_allocate:
11829   case OMPC_flush:
11830   case OMPC_read:
11831   case OMPC_write:
11832   case OMPC_update:
11833   case OMPC_capture:
11834   case OMPC_seq_cst:
11835   case OMPC_acq_rel:
11836   case OMPC_acquire:
11837   case OMPC_release:
11838   case OMPC_relaxed:
11839   case OMPC_depend:
11840   case OMPC_threads:
11841   case OMPC_simd:
11842   case OMPC_map:
11843   case OMPC_nogroup:
11844   case OMPC_dist_schedule:
11845   case OMPC_defaultmap:
11846   case OMPC_unknown:
11847   case OMPC_uniform:
11848   case OMPC_to:
11849   case OMPC_from:
11850   case OMPC_use_device_ptr:
11851   case OMPC_use_device_addr:
11852   case OMPC_is_device_ptr:
11853   case OMPC_unified_address:
11854   case OMPC_unified_shared_memory:
11855   case OMPC_reverse_offload:
11856   case OMPC_dynamic_allocators:
11857   case OMPC_atomic_default_mem_order:
11858   case OMPC_device_type:
11859   case OMPC_match:
11860   case OMPC_nontemporal:
11861   case OMPC_order:
11862   case OMPC_destroy:
11863   case OMPC_inclusive:
11864   case OMPC_exclusive:
11865   case OMPC_uses_allocators:
11866   case OMPC_affinity:
11867   default:
11868     llvm_unreachable("Clause is not allowed.");
11869   }
11870   return Res;
11871 }
11872 
11873 // An OpenMP directive such as 'target parallel' has two captured regions:
11874 // for the 'target' and 'parallel' respectively.  This function returns
11875 // the region in which to capture expressions associated with a clause.
11876 // A return value of OMPD_unknown signifies that the expression should not
11877 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)11878 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
11879     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
11880     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
11881   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11882   switch (CKind) {
11883   case OMPC_if:
11884     switch (DKind) {
11885     case OMPD_target_parallel_for_simd:
11886       if (OpenMPVersion >= 50 &&
11887           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11888         CaptureRegion = OMPD_parallel;
11889         break;
11890       }
11891       LLVM_FALLTHROUGH;
11892     case OMPD_target_parallel:
11893     case OMPD_target_parallel_for:
11894       // If this clause applies to the nested 'parallel' region, capture within
11895       // the 'target' region, otherwise do not capture.
11896       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11897         CaptureRegion = OMPD_target;
11898       break;
11899     case OMPD_target_teams_distribute_parallel_for_simd:
11900       if (OpenMPVersion >= 50 &&
11901           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11902         CaptureRegion = OMPD_parallel;
11903         break;
11904       }
11905       LLVM_FALLTHROUGH;
11906     case OMPD_target_teams_distribute_parallel_for:
11907       // If this clause applies to the nested 'parallel' region, capture within
11908       // the 'teams' region, otherwise do not capture.
11909       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11910         CaptureRegion = OMPD_teams;
11911       break;
11912     case OMPD_teams_distribute_parallel_for_simd:
11913       if (OpenMPVersion >= 50 &&
11914           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11915         CaptureRegion = OMPD_parallel;
11916         break;
11917       }
11918       LLVM_FALLTHROUGH;
11919     case OMPD_teams_distribute_parallel_for:
11920       CaptureRegion = OMPD_teams;
11921       break;
11922     case OMPD_target_update:
11923     case OMPD_target_enter_data:
11924     case OMPD_target_exit_data:
11925       CaptureRegion = OMPD_task;
11926       break;
11927     case OMPD_parallel_master_taskloop:
11928       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11929         CaptureRegion = OMPD_parallel;
11930       break;
11931     case OMPD_parallel_master_taskloop_simd:
11932       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11933           NameModifier == OMPD_taskloop) {
11934         CaptureRegion = OMPD_parallel;
11935         break;
11936       }
11937       if (OpenMPVersion <= 45)
11938         break;
11939       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11940         CaptureRegion = OMPD_taskloop;
11941       break;
11942     case OMPD_parallel_for_simd:
11943       if (OpenMPVersion <= 45)
11944         break;
11945       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11946         CaptureRegion = OMPD_parallel;
11947       break;
11948     case OMPD_taskloop_simd:
11949     case OMPD_master_taskloop_simd:
11950       if (OpenMPVersion <= 45)
11951         break;
11952       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11953         CaptureRegion = OMPD_taskloop;
11954       break;
11955     case OMPD_distribute_parallel_for_simd:
11956       if (OpenMPVersion <= 45)
11957         break;
11958       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11959         CaptureRegion = OMPD_parallel;
11960       break;
11961     case OMPD_target_simd:
11962       if (OpenMPVersion >= 50 &&
11963           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11964         CaptureRegion = OMPD_target;
11965       break;
11966     case OMPD_teams_distribute_simd:
11967     case OMPD_target_teams_distribute_simd:
11968       if (OpenMPVersion >= 50 &&
11969           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11970         CaptureRegion = OMPD_teams;
11971       break;
11972     case OMPD_cancel:
11973     case OMPD_parallel:
11974     case OMPD_parallel_master:
11975     case OMPD_parallel_sections:
11976     case OMPD_parallel_for:
11977     case OMPD_target:
11978     case OMPD_target_teams:
11979     case OMPD_target_teams_distribute:
11980     case OMPD_distribute_parallel_for:
11981     case OMPD_task:
11982     case OMPD_taskloop:
11983     case OMPD_master_taskloop:
11984     case OMPD_target_data:
11985     case OMPD_simd:
11986     case OMPD_for_simd:
11987     case OMPD_distribute_simd:
11988       // Do not capture if-clause expressions.
11989       break;
11990     case OMPD_threadprivate:
11991     case OMPD_allocate:
11992     case OMPD_taskyield:
11993     case OMPD_barrier:
11994     case OMPD_taskwait:
11995     case OMPD_cancellation_point:
11996     case OMPD_flush:
11997     case OMPD_depobj:
11998     case OMPD_scan:
11999     case OMPD_declare_reduction:
12000     case OMPD_declare_mapper:
12001     case OMPD_declare_simd:
12002     case OMPD_declare_variant:
12003     case OMPD_begin_declare_variant:
12004     case OMPD_end_declare_variant:
12005     case OMPD_declare_target:
12006     case OMPD_end_declare_target:
12007     case OMPD_teams:
12008     case OMPD_for:
12009     case OMPD_sections:
12010     case OMPD_section:
12011     case OMPD_single:
12012     case OMPD_master:
12013     case OMPD_critical:
12014     case OMPD_taskgroup:
12015     case OMPD_distribute:
12016     case OMPD_ordered:
12017     case OMPD_atomic:
12018     case OMPD_teams_distribute:
12019     case OMPD_requires:
12020       llvm_unreachable("Unexpected OpenMP directive with if-clause");
12021     case OMPD_unknown:
12022     default:
12023       llvm_unreachable("Unknown OpenMP directive");
12024     }
12025     break;
12026   case OMPC_num_threads:
12027     switch (DKind) {
12028     case OMPD_target_parallel:
12029     case OMPD_target_parallel_for:
12030     case OMPD_target_parallel_for_simd:
12031       CaptureRegion = OMPD_target;
12032       break;
12033     case OMPD_teams_distribute_parallel_for:
12034     case OMPD_teams_distribute_parallel_for_simd:
12035     case OMPD_target_teams_distribute_parallel_for:
12036     case OMPD_target_teams_distribute_parallel_for_simd:
12037       CaptureRegion = OMPD_teams;
12038       break;
12039     case OMPD_parallel:
12040     case OMPD_parallel_master:
12041     case OMPD_parallel_sections:
12042     case OMPD_parallel_for:
12043     case OMPD_parallel_for_simd:
12044     case OMPD_distribute_parallel_for:
12045     case OMPD_distribute_parallel_for_simd:
12046     case OMPD_parallel_master_taskloop:
12047     case OMPD_parallel_master_taskloop_simd:
12048       // Do not capture num_threads-clause expressions.
12049       break;
12050     case OMPD_target_data:
12051     case OMPD_target_enter_data:
12052     case OMPD_target_exit_data:
12053     case OMPD_target_update:
12054     case OMPD_target:
12055     case OMPD_target_simd:
12056     case OMPD_target_teams:
12057     case OMPD_target_teams_distribute:
12058     case OMPD_target_teams_distribute_simd:
12059     case OMPD_cancel:
12060     case OMPD_task:
12061     case OMPD_taskloop:
12062     case OMPD_taskloop_simd:
12063     case OMPD_master_taskloop:
12064     case OMPD_master_taskloop_simd:
12065     case OMPD_threadprivate:
12066     case OMPD_allocate:
12067     case OMPD_taskyield:
12068     case OMPD_barrier:
12069     case OMPD_taskwait:
12070     case OMPD_cancellation_point:
12071     case OMPD_flush:
12072     case OMPD_depobj:
12073     case OMPD_scan:
12074     case OMPD_declare_reduction:
12075     case OMPD_declare_mapper:
12076     case OMPD_declare_simd:
12077     case OMPD_declare_variant:
12078     case OMPD_begin_declare_variant:
12079     case OMPD_end_declare_variant:
12080     case OMPD_declare_target:
12081     case OMPD_end_declare_target:
12082     case OMPD_teams:
12083     case OMPD_simd:
12084     case OMPD_for:
12085     case OMPD_for_simd:
12086     case OMPD_sections:
12087     case OMPD_section:
12088     case OMPD_single:
12089     case OMPD_master:
12090     case OMPD_critical:
12091     case OMPD_taskgroup:
12092     case OMPD_distribute:
12093     case OMPD_ordered:
12094     case OMPD_atomic:
12095     case OMPD_distribute_simd:
12096     case OMPD_teams_distribute:
12097     case OMPD_teams_distribute_simd:
12098     case OMPD_requires:
12099       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
12100     case OMPD_unknown:
12101     default:
12102       llvm_unreachable("Unknown OpenMP directive");
12103     }
12104     break;
12105   case OMPC_num_teams:
12106     switch (DKind) {
12107     case OMPD_target_teams:
12108     case OMPD_target_teams_distribute:
12109     case OMPD_target_teams_distribute_simd:
12110     case OMPD_target_teams_distribute_parallel_for:
12111     case OMPD_target_teams_distribute_parallel_for_simd:
12112       CaptureRegion = OMPD_target;
12113       break;
12114     case OMPD_teams_distribute_parallel_for:
12115     case OMPD_teams_distribute_parallel_for_simd:
12116     case OMPD_teams:
12117     case OMPD_teams_distribute:
12118     case OMPD_teams_distribute_simd:
12119       // Do not capture num_teams-clause expressions.
12120       break;
12121     case OMPD_distribute_parallel_for:
12122     case OMPD_distribute_parallel_for_simd:
12123     case OMPD_task:
12124     case OMPD_taskloop:
12125     case OMPD_taskloop_simd:
12126     case OMPD_master_taskloop:
12127     case OMPD_master_taskloop_simd:
12128     case OMPD_parallel_master_taskloop:
12129     case OMPD_parallel_master_taskloop_simd:
12130     case OMPD_target_data:
12131     case OMPD_target_enter_data:
12132     case OMPD_target_exit_data:
12133     case OMPD_target_update:
12134     case OMPD_cancel:
12135     case OMPD_parallel:
12136     case OMPD_parallel_master:
12137     case OMPD_parallel_sections:
12138     case OMPD_parallel_for:
12139     case OMPD_parallel_for_simd:
12140     case OMPD_target:
12141     case OMPD_target_simd:
12142     case OMPD_target_parallel:
12143     case OMPD_target_parallel_for:
12144     case OMPD_target_parallel_for_simd:
12145     case OMPD_threadprivate:
12146     case OMPD_allocate:
12147     case OMPD_taskyield:
12148     case OMPD_barrier:
12149     case OMPD_taskwait:
12150     case OMPD_cancellation_point:
12151     case OMPD_flush:
12152     case OMPD_depobj:
12153     case OMPD_scan:
12154     case OMPD_declare_reduction:
12155     case OMPD_declare_mapper:
12156     case OMPD_declare_simd:
12157     case OMPD_declare_variant:
12158     case OMPD_begin_declare_variant:
12159     case OMPD_end_declare_variant:
12160     case OMPD_declare_target:
12161     case OMPD_end_declare_target:
12162     case OMPD_simd:
12163     case OMPD_for:
12164     case OMPD_for_simd:
12165     case OMPD_sections:
12166     case OMPD_section:
12167     case OMPD_single:
12168     case OMPD_master:
12169     case OMPD_critical:
12170     case OMPD_taskgroup:
12171     case OMPD_distribute:
12172     case OMPD_ordered:
12173     case OMPD_atomic:
12174     case OMPD_distribute_simd:
12175     case OMPD_requires:
12176       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12177     case OMPD_unknown:
12178     default:
12179       llvm_unreachable("Unknown OpenMP directive");
12180     }
12181     break;
12182   case OMPC_thread_limit:
12183     switch (DKind) {
12184     case OMPD_target_teams:
12185     case OMPD_target_teams_distribute:
12186     case OMPD_target_teams_distribute_simd:
12187     case OMPD_target_teams_distribute_parallel_for:
12188     case OMPD_target_teams_distribute_parallel_for_simd:
12189       CaptureRegion = OMPD_target;
12190       break;
12191     case OMPD_teams_distribute_parallel_for:
12192     case OMPD_teams_distribute_parallel_for_simd:
12193     case OMPD_teams:
12194     case OMPD_teams_distribute:
12195     case OMPD_teams_distribute_simd:
12196       // Do not capture thread_limit-clause expressions.
12197       break;
12198     case OMPD_distribute_parallel_for:
12199     case OMPD_distribute_parallel_for_simd:
12200     case OMPD_task:
12201     case OMPD_taskloop:
12202     case OMPD_taskloop_simd:
12203     case OMPD_master_taskloop:
12204     case OMPD_master_taskloop_simd:
12205     case OMPD_parallel_master_taskloop:
12206     case OMPD_parallel_master_taskloop_simd:
12207     case OMPD_target_data:
12208     case OMPD_target_enter_data:
12209     case OMPD_target_exit_data:
12210     case OMPD_target_update:
12211     case OMPD_cancel:
12212     case OMPD_parallel:
12213     case OMPD_parallel_master:
12214     case OMPD_parallel_sections:
12215     case OMPD_parallel_for:
12216     case OMPD_parallel_for_simd:
12217     case OMPD_target:
12218     case OMPD_target_simd:
12219     case OMPD_target_parallel:
12220     case OMPD_target_parallel_for:
12221     case OMPD_target_parallel_for_simd:
12222     case OMPD_threadprivate:
12223     case OMPD_allocate:
12224     case OMPD_taskyield:
12225     case OMPD_barrier:
12226     case OMPD_taskwait:
12227     case OMPD_cancellation_point:
12228     case OMPD_flush:
12229     case OMPD_depobj:
12230     case OMPD_scan:
12231     case OMPD_declare_reduction:
12232     case OMPD_declare_mapper:
12233     case OMPD_declare_simd:
12234     case OMPD_declare_variant:
12235     case OMPD_begin_declare_variant:
12236     case OMPD_end_declare_variant:
12237     case OMPD_declare_target:
12238     case OMPD_end_declare_target:
12239     case OMPD_simd:
12240     case OMPD_for:
12241     case OMPD_for_simd:
12242     case OMPD_sections:
12243     case OMPD_section:
12244     case OMPD_single:
12245     case OMPD_master:
12246     case OMPD_critical:
12247     case OMPD_taskgroup:
12248     case OMPD_distribute:
12249     case OMPD_ordered:
12250     case OMPD_atomic:
12251     case OMPD_distribute_simd:
12252     case OMPD_requires:
12253       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
12254     case OMPD_unknown:
12255     default:
12256       llvm_unreachable("Unknown OpenMP directive");
12257     }
12258     break;
12259   case OMPC_schedule:
12260     switch (DKind) {
12261     case OMPD_parallel_for:
12262     case OMPD_parallel_for_simd:
12263     case OMPD_distribute_parallel_for:
12264     case OMPD_distribute_parallel_for_simd:
12265     case OMPD_teams_distribute_parallel_for:
12266     case OMPD_teams_distribute_parallel_for_simd:
12267     case OMPD_target_parallel_for:
12268     case OMPD_target_parallel_for_simd:
12269     case OMPD_target_teams_distribute_parallel_for:
12270     case OMPD_target_teams_distribute_parallel_for_simd:
12271       CaptureRegion = OMPD_parallel;
12272       break;
12273     case OMPD_for:
12274     case OMPD_for_simd:
12275       // Do not capture schedule-clause expressions.
12276       break;
12277     case OMPD_task:
12278     case OMPD_taskloop:
12279     case OMPD_taskloop_simd:
12280     case OMPD_master_taskloop:
12281     case OMPD_master_taskloop_simd:
12282     case OMPD_parallel_master_taskloop:
12283     case OMPD_parallel_master_taskloop_simd:
12284     case OMPD_target_data:
12285     case OMPD_target_enter_data:
12286     case OMPD_target_exit_data:
12287     case OMPD_target_update:
12288     case OMPD_teams:
12289     case OMPD_teams_distribute:
12290     case OMPD_teams_distribute_simd:
12291     case OMPD_target_teams_distribute:
12292     case OMPD_target_teams_distribute_simd:
12293     case OMPD_target:
12294     case OMPD_target_simd:
12295     case OMPD_target_parallel:
12296     case OMPD_cancel:
12297     case OMPD_parallel:
12298     case OMPD_parallel_master:
12299     case OMPD_parallel_sections:
12300     case OMPD_threadprivate:
12301     case OMPD_allocate:
12302     case OMPD_taskyield:
12303     case OMPD_barrier:
12304     case OMPD_taskwait:
12305     case OMPD_cancellation_point:
12306     case OMPD_flush:
12307     case OMPD_depobj:
12308     case OMPD_scan:
12309     case OMPD_declare_reduction:
12310     case OMPD_declare_mapper:
12311     case OMPD_declare_simd:
12312     case OMPD_declare_variant:
12313     case OMPD_begin_declare_variant:
12314     case OMPD_end_declare_variant:
12315     case OMPD_declare_target:
12316     case OMPD_end_declare_target:
12317     case OMPD_simd:
12318     case OMPD_sections:
12319     case OMPD_section:
12320     case OMPD_single:
12321     case OMPD_master:
12322     case OMPD_critical:
12323     case OMPD_taskgroup:
12324     case OMPD_distribute:
12325     case OMPD_ordered:
12326     case OMPD_atomic:
12327     case OMPD_distribute_simd:
12328     case OMPD_target_teams:
12329     case OMPD_requires:
12330       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12331     case OMPD_unknown:
12332     default:
12333       llvm_unreachable("Unknown OpenMP directive");
12334     }
12335     break;
12336   case OMPC_dist_schedule:
12337     switch (DKind) {
12338     case OMPD_teams_distribute_parallel_for:
12339     case OMPD_teams_distribute_parallel_for_simd:
12340     case OMPD_teams_distribute:
12341     case OMPD_teams_distribute_simd:
12342     case OMPD_target_teams_distribute_parallel_for:
12343     case OMPD_target_teams_distribute_parallel_for_simd:
12344     case OMPD_target_teams_distribute:
12345     case OMPD_target_teams_distribute_simd:
12346       CaptureRegion = OMPD_teams;
12347       break;
12348     case OMPD_distribute_parallel_for:
12349     case OMPD_distribute_parallel_for_simd:
12350     case OMPD_distribute:
12351     case OMPD_distribute_simd:
12352       // Do not capture thread_limit-clause expressions.
12353       break;
12354     case OMPD_parallel_for:
12355     case OMPD_parallel_for_simd:
12356     case OMPD_target_parallel_for_simd:
12357     case OMPD_target_parallel_for:
12358     case OMPD_task:
12359     case OMPD_taskloop:
12360     case OMPD_taskloop_simd:
12361     case OMPD_master_taskloop:
12362     case OMPD_master_taskloop_simd:
12363     case OMPD_parallel_master_taskloop:
12364     case OMPD_parallel_master_taskloop_simd:
12365     case OMPD_target_data:
12366     case OMPD_target_enter_data:
12367     case OMPD_target_exit_data:
12368     case OMPD_target_update:
12369     case OMPD_teams:
12370     case OMPD_target:
12371     case OMPD_target_simd:
12372     case OMPD_target_parallel:
12373     case OMPD_cancel:
12374     case OMPD_parallel:
12375     case OMPD_parallel_master:
12376     case OMPD_parallel_sections:
12377     case OMPD_threadprivate:
12378     case OMPD_allocate:
12379     case OMPD_taskyield:
12380     case OMPD_barrier:
12381     case OMPD_taskwait:
12382     case OMPD_cancellation_point:
12383     case OMPD_flush:
12384     case OMPD_depobj:
12385     case OMPD_scan:
12386     case OMPD_declare_reduction:
12387     case OMPD_declare_mapper:
12388     case OMPD_declare_simd:
12389     case OMPD_declare_variant:
12390     case OMPD_begin_declare_variant:
12391     case OMPD_end_declare_variant:
12392     case OMPD_declare_target:
12393     case OMPD_end_declare_target:
12394     case OMPD_simd:
12395     case OMPD_for:
12396     case OMPD_for_simd:
12397     case OMPD_sections:
12398     case OMPD_section:
12399     case OMPD_single:
12400     case OMPD_master:
12401     case OMPD_critical:
12402     case OMPD_taskgroup:
12403     case OMPD_ordered:
12404     case OMPD_atomic:
12405     case OMPD_target_teams:
12406     case OMPD_requires:
12407       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12408     case OMPD_unknown:
12409     default:
12410       llvm_unreachable("Unknown OpenMP directive");
12411     }
12412     break;
12413   case OMPC_device:
12414     switch (DKind) {
12415     case OMPD_target_update:
12416     case OMPD_target_enter_data:
12417     case OMPD_target_exit_data:
12418     case OMPD_target:
12419     case OMPD_target_simd:
12420     case OMPD_target_teams:
12421     case OMPD_target_parallel:
12422     case OMPD_target_teams_distribute:
12423     case OMPD_target_teams_distribute_simd:
12424     case OMPD_target_parallel_for:
12425     case OMPD_target_parallel_for_simd:
12426     case OMPD_target_teams_distribute_parallel_for:
12427     case OMPD_target_teams_distribute_parallel_for_simd:
12428       CaptureRegion = OMPD_task;
12429       break;
12430     case OMPD_target_data:
12431       // Do not capture device-clause expressions.
12432       break;
12433     case OMPD_teams_distribute_parallel_for:
12434     case OMPD_teams_distribute_parallel_for_simd:
12435     case OMPD_teams:
12436     case OMPD_teams_distribute:
12437     case OMPD_teams_distribute_simd:
12438     case OMPD_distribute_parallel_for:
12439     case OMPD_distribute_parallel_for_simd:
12440     case OMPD_task:
12441     case OMPD_taskloop:
12442     case OMPD_taskloop_simd:
12443     case OMPD_master_taskloop:
12444     case OMPD_master_taskloop_simd:
12445     case OMPD_parallel_master_taskloop:
12446     case OMPD_parallel_master_taskloop_simd:
12447     case OMPD_cancel:
12448     case OMPD_parallel:
12449     case OMPD_parallel_master:
12450     case OMPD_parallel_sections:
12451     case OMPD_parallel_for:
12452     case OMPD_parallel_for_simd:
12453     case OMPD_threadprivate:
12454     case OMPD_allocate:
12455     case OMPD_taskyield:
12456     case OMPD_barrier:
12457     case OMPD_taskwait:
12458     case OMPD_cancellation_point:
12459     case OMPD_flush:
12460     case OMPD_depobj:
12461     case OMPD_scan:
12462     case OMPD_declare_reduction:
12463     case OMPD_declare_mapper:
12464     case OMPD_declare_simd:
12465     case OMPD_declare_variant:
12466     case OMPD_begin_declare_variant:
12467     case OMPD_end_declare_variant:
12468     case OMPD_declare_target:
12469     case OMPD_end_declare_target:
12470     case OMPD_simd:
12471     case OMPD_for:
12472     case OMPD_for_simd:
12473     case OMPD_sections:
12474     case OMPD_section:
12475     case OMPD_single:
12476     case OMPD_master:
12477     case OMPD_critical:
12478     case OMPD_taskgroup:
12479     case OMPD_distribute:
12480     case OMPD_ordered:
12481     case OMPD_atomic:
12482     case OMPD_distribute_simd:
12483     case OMPD_requires:
12484       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12485     case OMPD_unknown:
12486     default:
12487       llvm_unreachable("Unknown OpenMP directive");
12488     }
12489     break;
12490   case OMPC_grainsize:
12491   case OMPC_num_tasks:
12492   case OMPC_final:
12493   case OMPC_priority:
12494     switch (DKind) {
12495     case OMPD_task:
12496     case OMPD_taskloop:
12497     case OMPD_taskloop_simd:
12498     case OMPD_master_taskloop:
12499     case OMPD_master_taskloop_simd:
12500       break;
12501     case OMPD_parallel_master_taskloop:
12502     case OMPD_parallel_master_taskloop_simd:
12503       CaptureRegion = OMPD_parallel;
12504       break;
12505     case OMPD_target_update:
12506     case OMPD_target_enter_data:
12507     case OMPD_target_exit_data:
12508     case OMPD_target:
12509     case OMPD_target_simd:
12510     case OMPD_target_teams:
12511     case OMPD_target_parallel:
12512     case OMPD_target_teams_distribute:
12513     case OMPD_target_teams_distribute_simd:
12514     case OMPD_target_parallel_for:
12515     case OMPD_target_parallel_for_simd:
12516     case OMPD_target_teams_distribute_parallel_for:
12517     case OMPD_target_teams_distribute_parallel_for_simd:
12518     case OMPD_target_data:
12519     case OMPD_teams_distribute_parallel_for:
12520     case OMPD_teams_distribute_parallel_for_simd:
12521     case OMPD_teams:
12522     case OMPD_teams_distribute:
12523     case OMPD_teams_distribute_simd:
12524     case OMPD_distribute_parallel_for:
12525     case OMPD_distribute_parallel_for_simd:
12526     case OMPD_cancel:
12527     case OMPD_parallel:
12528     case OMPD_parallel_master:
12529     case OMPD_parallel_sections:
12530     case OMPD_parallel_for:
12531     case OMPD_parallel_for_simd:
12532     case OMPD_threadprivate:
12533     case OMPD_allocate:
12534     case OMPD_taskyield:
12535     case OMPD_barrier:
12536     case OMPD_taskwait:
12537     case OMPD_cancellation_point:
12538     case OMPD_flush:
12539     case OMPD_depobj:
12540     case OMPD_scan:
12541     case OMPD_declare_reduction:
12542     case OMPD_declare_mapper:
12543     case OMPD_declare_simd:
12544     case OMPD_declare_variant:
12545     case OMPD_begin_declare_variant:
12546     case OMPD_end_declare_variant:
12547     case OMPD_declare_target:
12548     case OMPD_end_declare_target:
12549     case OMPD_simd:
12550     case OMPD_for:
12551     case OMPD_for_simd:
12552     case OMPD_sections:
12553     case OMPD_section:
12554     case OMPD_single:
12555     case OMPD_master:
12556     case OMPD_critical:
12557     case OMPD_taskgroup:
12558     case OMPD_distribute:
12559     case OMPD_ordered:
12560     case OMPD_atomic:
12561     case OMPD_distribute_simd:
12562     case OMPD_requires:
12563       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
12564     case OMPD_unknown:
12565     default:
12566       llvm_unreachable("Unknown OpenMP directive");
12567     }
12568     break;
12569   case OMPC_firstprivate:
12570   case OMPC_lastprivate:
12571   case OMPC_reduction:
12572   case OMPC_task_reduction:
12573   case OMPC_in_reduction:
12574   case OMPC_linear:
12575   case OMPC_default:
12576   case OMPC_proc_bind:
12577   case OMPC_safelen:
12578   case OMPC_simdlen:
12579   case OMPC_allocator:
12580   case OMPC_collapse:
12581   case OMPC_private:
12582   case OMPC_shared:
12583   case OMPC_aligned:
12584   case OMPC_copyin:
12585   case OMPC_copyprivate:
12586   case OMPC_ordered:
12587   case OMPC_nowait:
12588   case OMPC_untied:
12589   case OMPC_mergeable:
12590   case OMPC_threadprivate:
12591   case OMPC_allocate:
12592   case OMPC_flush:
12593   case OMPC_depobj:
12594   case OMPC_read:
12595   case OMPC_write:
12596   case OMPC_update:
12597   case OMPC_capture:
12598   case OMPC_seq_cst:
12599   case OMPC_acq_rel:
12600   case OMPC_acquire:
12601   case OMPC_release:
12602   case OMPC_relaxed:
12603   case OMPC_depend:
12604   case OMPC_threads:
12605   case OMPC_simd:
12606   case OMPC_map:
12607   case OMPC_nogroup:
12608   case OMPC_hint:
12609   case OMPC_defaultmap:
12610   case OMPC_unknown:
12611   case OMPC_uniform:
12612   case OMPC_to:
12613   case OMPC_from:
12614   case OMPC_use_device_ptr:
12615   case OMPC_use_device_addr:
12616   case OMPC_is_device_ptr:
12617   case OMPC_unified_address:
12618   case OMPC_unified_shared_memory:
12619   case OMPC_reverse_offload:
12620   case OMPC_dynamic_allocators:
12621   case OMPC_atomic_default_mem_order:
12622   case OMPC_device_type:
12623   case OMPC_match:
12624   case OMPC_nontemporal:
12625   case OMPC_order:
12626   case OMPC_destroy:
12627   case OMPC_detach:
12628   case OMPC_inclusive:
12629   case OMPC_exclusive:
12630   case OMPC_uses_allocators:
12631   case OMPC_affinity:
12632   default:
12633     llvm_unreachable("Unexpected OpenMP clause.");
12634   }
12635   return CaptureRegion;
12636 }
12637 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)12638 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12639                                      Expr *Condition, SourceLocation StartLoc,
12640                                      SourceLocation LParenLoc,
12641                                      SourceLocation NameModifierLoc,
12642                                      SourceLocation ColonLoc,
12643                                      SourceLocation EndLoc) {
12644   Expr *ValExpr = Condition;
12645   Stmt *HelperValStmt = nullptr;
12646   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12647   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12648       !Condition->isInstantiationDependent() &&
12649       !Condition->containsUnexpandedParameterPack()) {
12650     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12651     if (Val.isInvalid())
12652       return nullptr;
12653 
12654     ValExpr = Val.get();
12655 
12656     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12657     CaptureRegion = getOpenMPCaptureRegionForClause(
12658         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12659     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12660       ValExpr = MakeFullExpr(ValExpr).get();
12661       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12662       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12663       HelperValStmt = buildPreInits(Context, Captures);
12664     }
12665   }
12666 
12667   return new (Context)
12668       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12669                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12670 }
12671 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12672 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12673                                         SourceLocation StartLoc,
12674                                         SourceLocation LParenLoc,
12675                                         SourceLocation EndLoc) {
12676   Expr *ValExpr = Condition;
12677   Stmt *HelperValStmt = nullptr;
12678   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12679   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12680       !Condition->isInstantiationDependent() &&
12681       !Condition->containsUnexpandedParameterPack()) {
12682     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12683     if (Val.isInvalid())
12684       return nullptr;
12685 
12686     ValExpr = MakeFullExpr(Val.get()).get();
12687 
12688     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12689     CaptureRegion =
12690         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12691     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12692       ValExpr = MakeFullExpr(ValExpr).get();
12693       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12694       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12695       HelperValStmt = buildPreInits(Context, Captures);
12696     }
12697   }
12698 
12699   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12700                                       StartLoc, LParenLoc, EndLoc);
12701 }
12702 
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)12703 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12704                                                         Expr *Op) {
12705   if (!Op)
12706     return ExprError();
12707 
12708   class IntConvertDiagnoser : public ICEConvertDiagnoser {
12709   public:
12710     IntConvertDiagnoser()
12711         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12712     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12713                                          QualType T) override {
12714       return S.Diag(Loc, diag::err_omp_not_integral) << T;
12715     }
12716     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12717                                              QualType T) override {
12718       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12719     }
12720     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12721                                                QualType T,
12722                                                QualType ConvTy) override {
12723       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12724     }
12725     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12726                                            QualType ConvTy) override {
12727       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12728              << ConvTy->isEnumeralType() << ConvTy;
12729     }
12730     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12731                                             QualType T) override {
12732       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12733     }
12734     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12735                                         QualType ConvTy) override {
12736       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12737              << ConvTy->isEnumeralType() << ConvTy;
12738     }
12739     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12740                                              QualType) override {
12741       llvm_unreachable("conversion functions are permitted");
12742     }
12743   } ConvertDiagnoser;
12744   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12745 }
12746 
12747 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)12748 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12749                           bool StrictlyPositive, bool BuildCapture = false,
12750                           OpenMPDirectiveKind DKind = OMPD_unknown,
12751                           OpenMPDirectiveKind *CaptureRegion = nullptr,
12752                           Stmt **HelperValStmt = nullptr) {
12753   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12754       !ValExpr->isInstantiationDependent()) {
12755     SourceLocation Loc = ValExpr->getExprLoc();
12756     ExprResult Value =
12757         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12758     if (Value.isInvalid())
12759       return false;
12760 
12761     ValExpr = Value.get();
12762     // The expression must evaluate to a non-negative integer value.
12763     if (Optional<llvm::APSInt> Result =
12764             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12765       if (Result->isSigned() &&
12766           !((!StrictlyPositive && Result->isNonNegative()) ||
12767             (StrictlyPositive && Result->isStrictlyPositive()))) {
12768         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12769             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12770             << ValExpr->getSourceRange();
12771         return false;
12772       }
12773     }
12774     if (!BuildCapture)
12775       return true;
12776     *CaptureRegion =
12777         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12778     if (*CaptureRegion != OMPD_unknown &&
12779         !SemaRef.CurContext->isDependentContext()) {
12780       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12781       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12782       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12783       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12784     }
12785   }
12786   return true;
12787 }
12788 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12789 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12790                                              SourceLocation StartLoc,
12791                                              SourceLocation LParenLoc,
12792                                              SourceLocation EndLoc) {
12793   Expr *ValExpr = NumThreads;
12794   Stmt *HelperValStmt = nullptr;
12795 
12796   // OpenMP [2.5, Restrictions]
12797   //  The num_threads expression must evaluate to a positive integer value.
12798   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12799                                  /*StrictlyPositive=*/true))
12800     return nullptr;
12801 
12802   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12803   OpenMPDirectiveKind CaptureRegion =
12804       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12805   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12806     ValExpr = MakeFullExpr(ValExpr).get();
12807     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12808     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12809     HelperValStmt = buildPreInits(Context, Captures);
12810   }
12811 
12812   return new (Context) OMPNumThreadsClause(
12813       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12814 }
12815 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)12816 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12817                                                        OpenMPClauseKind CKind,
12818                                                        bool StrictlyPositive) {
12819   if (!E)
12820     return ExprError();
12821   if (E->isValueDependent() || E->isTypeDependent() ||
12822       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12823     return E;
12824   llvm::APSInt Result;
12825   ExprResult ICE =
12826       VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
12827   if (ICE.isInvalid())
12828     return ExprError();
12829   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12830       (!StrictlyPositive && !Result.isNonNegative())) {
12831     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12832         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12833         << E->getSourceRange();
12834     return ExprError();
12835   }
12836   if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12837     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12838         << E->getSourceRange();
12839     return ExprError();
12840   }
12841   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
12842     DSAStack->setAssociatedLoops(Result.getExtValue());
12843   else if (CKind == OMPC_ordered)
12844     DSAStack->setAssociatedLoops(Result.getExtValue());
12845   return ICE;
12846 }
12847 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12848 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12849                                           SourceLocation LParenLoc,
12850                                           SourceLocation EndLoc) {
12851   // OpenMP [2.8.1, simd construct, Description]
12852   // The parameter of the safelen clause must be a constant
12853   // positive integer expression.
12854   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12855   if (Safelen.isInvalid())
12856     return nullptr;
12857   return new (Context)
12858       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12859 }
12860 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12861 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12862                                           SourceLocation LParenLoc,
12863                                           SourceLocation EndLoc) {
12864   // OpenMP [2.8.1, simd construct, Description]
12865   // The parameter of the simdlen clause must be a constant
12866   // positive integer expression.
12867   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
12868   if (Simdlen.isInvalid())
12869     return nullptr;
12870   return new (Context)
12871       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
12872 }
12873 
12874 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)12875 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
12876                                     DSAStackTy *Stack) {
12877   QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
12878   if (!OMPAllocatorHandleT.isNull())
12879     return true;
12880   // Build the predefined allocator expressions.
12881   bool ErrorFound = false;
12882   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
12883     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
12884     StringRef Allocator =
12885         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
12886     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
12887     auto *VD = dyn_cast_or_null<ValueDecl>(
12888         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
12889     if (!VD) {
12890       ErrorFound = true;
12891       break;
12892     }
12893     QualType AllocatorType =
12894         VD->getType().getNonLValueExprType(S.getASTContext());
12895     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
12896     if (!Res.isUsable()) {
12897       ErrorFound = true;
12898       break;
12899     }
12900     if (OMPAllocatorHandleT.isNull())
12901       OMPAllocatorHandleT = AllocatorType;
12902     if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
12903       ErrorFound = true;
12904       break;
12905     }
12906     Stack->setAllocator(AllocatorKind, Res.get());
12907   }
12908   if (ErrorFound) {
12909     S.Diag(Loc, diag::err_omp_implied_type_not_found)
12910         << "omp_allocator_handle_t";
12911     return false;
12912   }
12913   OMPAllocatorHandleT.addConst();
12914   Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
12915   return true;
12916 }
12917 
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12918 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
12919                                             SourceLocation LParenLoc,
12920                                             SourceLocation EndLoc) {
12921   // OpenMP [2.11.3, allocate Directive, Description]
12922   // allocator is an expression of omp_allocator_handle_t type.
12923   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
12924     return nullptr;
12925 
12926   ExprResult Allocator = DefaultLvalueConversion(A);
12927   if (Allocator.isInvalid())
12928     return nullptr;
12929   Allocator = PerformImplicitConversion(Allocator.get(),
12930                                         DSAStack->getOMPAllocatorHandleT(),
12931                                         Sema::AA_Initializing,
12932                                         /*AllowExplicit=*/true);
12933   if (Allocator.isInvalid())
12934     return nullptr;
12935   return new (Context)
12936       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12937 }
12938 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12939 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12940                                            SourceLocation StartLoc,
12941                                            SourceLocation LParenLoc,
12942                                            SourceLocation EndLoc) {
12943   // OpenMP [2.7.1, loop construct, Description]
12944   // OpenMP [2.8.1, simd construct, Description]
12945   // OpenMP [2.9.6, distribute construct, Description]
12946   // The parameter of the collapse clause must be a constant
12947   // positive integer expression.
12948   ExprResult NumForLoopsResult =
12949       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12950   if (NumForLoopsResult.isInvalid())
12951     return nullptr;
12952   return new (Context)
12953       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12954 }
12955 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)12956 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12957                                           SourceLocation EndLoc,
12958                                           SourceLocation LParenLoc,
12959                                           Expr *NumForLoops) {
12960   // OpenMP [2.7.1, loop construct, Description]
12961   // OpenMP [2.8.1, simd construct, Description]
12962   // OpenMP [2.9.6, distribute construct, Description]
12963   // The parameter of the ordered clause must be a constant
12964   // positive integer expression if any.
12965   if (NumForLoops && LParenLoc.isValid()) {
12966     ExprResult NumForLoopsResult =
12967         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12968     if (NumForLoopsResult.isInvalid())
12969       return nullptr;
12970     NumForLoops = NumForLoopsResult.get();
12971   } else {
12972     NumForLoops = nullptr;
12973   }
12974   auto *Clause = OMPOrderedClause::Create(
12975       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
12976       StartLoc, LParenLoc, EndLoc);
12977   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12978   return Clause;
12979 }
12980 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12981 OMPClause *Sema::ActOnOpenMPSimpleClause(
12982     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12983     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12984   OMPClause *Res = nullptr;
12985   switch (Kind) {
12986   case OMPC_default:
12987     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12988                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12989     break;
12990   case OMPC_proc_bind:
12991     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12992                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12993     break;
12994   case OMPC_atomic_default_mem_order:
12995     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12996         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12997         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12998     break;
12999   case OMPC_order:
13000     Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
13001                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13002     break;
13003   case OMPC_update:
13004     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
13005                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
13006     break;
13007   case OMPC_if:
13008   case OMPC_final:
13009   case OMPC_num_threads:
13010   case OMPC_safelen:
13011   case OMPC_simdlen:
13012   case OMPC_allocator:
13013   case OMPC_collapse:
13014   case OMPC_schedule:
13015   case OMPC_private:
13016   case OMPC_firstprivate:
13017   case OMPC_lastprivate:
13018   case OMPC_shared:
13019   case OMPC_reduction:
13020   case OMPC_task_reduction:
13021   case OMPC_in_reduction:
13022   case OMPC_linear:
13023   case OMPC_aligned:
13024   case OMPC_copyin:
13025   case OMPC_copyprivate:
13026   case OMPC_ordered:
13027   case OMPC_nowait:
13028   case OMPC_untied:
13029   case OMPC_mergeable:
13030   case OMPC_threadprivate:
13031   case OMPC_allocate:
13032   case OMPC_flush:
13033   case OMPC_depobj:
13034   case OMPC_read:
13035   case OMPC_write:
13036   case OMPC_capture:
13037   case OMPC_seq_cst:
13038   case OMPC_acq_rel:
13039   case OMPC_acquire:
13040   case OMPC_release:
13041   case OMPC_relaxed:
13042   case OMPC_depend:
13043   case OMPC_device:
13044   case OMPC_threads:
13045   case OMPC_simd:
13046   case OMPC_map:
13047   case OMPC_num_teams:
13048   case OMPC_thread_limit:
13049   case OMPC_priority:
13050   case OMPC_grainsize:
13051   case OMPC_nogroup:
13052   case OMPC_num_tasks:
13053   case OMPC_hint:
13054   case OMPC_dist_schedule:
13055   case OMPC_defaultmap:
13056   case OMPC_unknown:
13057   case OMPC_uniform:
13058   case OMPC_to:
13059   case OMPC_from:
13060   case OMPC_use_device_ptr:
13061   case OMPC_use_device_addr:
13062   case OMPC_is_device_ptr:
13063   case OMPC_unified_address:
13064   case OMPC_unified_shared_memory:
13065   case OMPC_reverse_offload:
13066   case OMPC_dynamic_allocators:
13067   case OMPC_device_type:
13068   case OMPC_match:
13069   case OMPC_nontemporal:
13070   case OMPC_destroy:
13071   case OMPC_detach:
13072   case OMPC_inclusive:
13073   case OMPC_exclusive:
13074   case OMPC_uses_allocators:
13075   case OMPC_affinity:
13076   default:
13077     llvm_unreachable("Clause is not allowed.");
13078   }
13079   return Res;
13080 }
13081 
13082 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)13083 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
13084                         ArrayRef<unsigned> Exclude = llvm::None) {
13085   SmallString<256> Buffer;
13086   llvm::raw_svector_ostream Out(Buffer);
13087   unsigned Skipped = Exclude.size();
13088   auto S = Exclude.begin(), E = Exclude.end();
13089   for (unsigned I = First; I < Last; ++I) {
13090     if (std::find(S, E, I) != E) {
13091       --Skipped;
13092       continue;
13093     }
13094     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
13095     if (I + Skipped + 2 == Last)
13096       Out << " or ";
13097     else if (I + Skipped + 1 != Last)
13098       Out << ", ";
13099   }
13100   return std::string(Out.str());
13101 }
13102 
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13103 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
13104                                           SourceLocation KindKwLoc,
13105                                           SourceLocation StartLoc,
13106                                           SourceLocation LParenLoc,
13107                                           SourceLocation EndLoc) {
13108   if (Kind == OMP_DEFAULT_unknown) {
13109     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13110         << getListOfPossibleValues(OMPC_default, /*First=*/0,
13111                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
13112         << getOpenMPClauseName(OMPC_default);
13113     return nullptr;
13114   }
13115 
13116   switch (Kind) {
13117   case OMP_DEFAULT_none:
13118     DSAStack->setDefaultDSANone(KindKwLoc);
13119     break;
13120   case OMP_DEFAULT_shared:
13121     DSAStack->setDefaultDSAShared(KindKwLoc);
13122     break;
13123   case OMP_DEFAULT_firstprivate:
13124     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
13125     break;
13126   default:
13127     llvm_unreachable("DSA unexpected in OpenMP default clause");
13128   }
13129 
13130   return new (Context)
13131       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13132 }
13133 
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13134 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13135                                            SourceLocation KindKwLoc,
13136                                            SourceLocation StartLoc,
13137                                            SourceLocation LParenLoc,
13138                                            SourceLocation EndLoc) {
13139   if (Kind == OMP_PROC_BIND_unknown) {
13140     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13141         << getListOfPossibleValues(OMPC_proc_bind,
13142                                    /*First=*/unsigned(OMP_PROC_BIND_master),
13143                                    /*Last=*/5)
13144         << getOpenMPClauseName(OMPC_proc_bind);
13145     return nullptr;
13146   }
13147   return new (Context)
13148       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13149 }
13150 
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13151 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13152     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13153     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13154   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13155     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13156         << getListOfPossibleValues(
13157                OMPC_atomic_default_mem_order, /*First=*/0,
13158                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13159         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13160     return nullptr;
13161   }
13162   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13163                                                       LParenLoc, EndLoc);
13164 }
13165 
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13166 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13167                                         SourceLocation KindKwLoc,
13168                                         SourceLocation StartLoc,
13169                                         SourceLocation LParenLoc,
13170                                         SourceLocation EndLoc) {
13171   if (Kind == OMPC_ORDER_unknown) {
13172     static_assert(OMPC_ORDER_unknown > 0,
13173                   "OMPC_ORDER_unknown not greater than 0");
13174     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13175         << getListOfPossibleValues(OMPC_order, /*First=*/0,
13176                                    /*Last=*/OMPC_ORDER_unknown)
13177         << getOpenMPClauseName(OMPC_order);
13178     return nullptr;
13179   }
13180   return new (Context)
13181       OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13182 }
13183 
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13184 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13185                                          SourceLocation KindKwLoc,
13186                                          SourceLocation StartLoc,
13187                                          SourceLocation LParenLoc,
13188                                          SourceLocation EndLoc) {
13189   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13190       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13191     unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13192                          OMPC_DEPEND_depobj};
13193     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13194         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13195                                    /*Last=*/OMPC_DEPEND_unknown, Except)
13196         << getOpenMPClauseName(OMPC_update);
13197     return nullptr;
13198   }
13199   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13200                                  EndLoc);
13201 }
13202 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)13203 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13204     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13205     SourceLocation StartLoc, SourceLocation LParenLoc,
13206     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13207     SourceLocation EndLoc) {
13208   OMPClause *Res = nullptr;
13209   switch (Kind) {
13210   case OMPC_schedule:
13211     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13212     assert(Argument.size() == NumberOfElements &&
13213            ArgumentLoc.size() == NumberOfElements);
13214     Res = ActOnOpenMPScheduleClause(
13215         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13216         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13217         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13218         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13219         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13220     break;
13221   case OMPC_if:
13222     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13223     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13224                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13225                               DelimLoc, EndLoc);
13226     break;
13227   case OMPC_dist_schedule:
13228     Res = ActOnOpenMPDistScheduleClause(
13229         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13230         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13231     break;
13232   case OMPC_defaultmap:
13233     enum { Modifier, DefaultmapKind };
13234     Res = ActOnOpenMPDefaultmapClause(
13235         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13236         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13237         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13238         EndLoc);
13239     break;
13240   case OMPC_device:
13241     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13242     Res = ActOnOpenMPDeviceClause(
13243         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13244         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13245     break;
13246   case OMPC_final:
13247   case OMPC_num_threads:
13248   case OMPC_safelen:
13249   case OMPC_simdlen:
13250   case OMPC_allocator:
13251   case OMPC_collapse:
13252   case OMPC_default:
13253   case OMPC_proc_bind:
13254   case OMPC_private:
13255   case OMPC_firstprivate:
13256   case OMPC_lastprivate:
13257   case OMPC_shared:
13258   case OMPC_reduction:
13259   case OMPC_task_reduction:
13260   case OMPC_in_reduction:
13261   case OMPC_linear:
13262   case OMPC_aligned:
13263   case OMPC_copyin:
13264   case OMPC_copyprivate:
13265   case OMPC_ordered:
13266   case OMPC_nowait:
13267   case OMPC_untied:
13268   case OMPC_mergeable:
13269   case OMPC_threadprivate:
13270   case OMPC_allocate:
13271   case OMPC_flush:
13272   case OMPC_depobj:
13273   case OMPC_read:
13274   case OMPC_write:
13275   case OMPC_update:
13276   case OMPC_capture:
13277   case OMPC_seq_cst:
13278   case OMPC_acq_rel:
13279   case OMPC_acquire:
13280   case OMPC_release:
13281   case OMPC_relaxed:
13282   case OMPC_depend:
13283   case OMPC_threads:
13284   case OMPC_simd:
13285   case OMPC_map:
13286   case OMPC_num_teams:
13287   case OMPC_thread_limit:
13288   case OMPC_priority:
13289   case OMPC_grainsize:
13290   case OMPC_nogroup:
13291   case OMPC_num_tasks:
13292   case OMPC_hint:
13293   case OMPC_unknown:
13294   case OMPC_uniform:
13295   case OMPC_to:
13296   case OMPC_from:
13297   case OMPC_use_device_ptr:
13298   case OMPC_use_device_addr:
13299   case OMPC_is_device_ptr:
13300   case OMPC_unified_address:
13301   case OMPC_unified_shared_memory:
13302   case OMPC_reverse_offload:
13303   case OMPC_dynamic_allocators:
13304   case OMPC_atomic_default_mem_order:
13305   case OMPC_device_type:
13306   case OMPC_match:
13307   case OMPC_nontemporal:
13308   case OMPC_order:
13309   case OMPC_destroy:
13310   case OMPC_detach:
13311   case OMPC_inclusive:
13312   case OMPC_exclusive:
13313   case OMPC_uses_allocators:
13314   case OMPC_affinity:
13315   default:
13316     llvm_unreachable("Clause is not allowed.");
13317   }
13318   return Res;
13319 }
13320 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)13321 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13322                                    OpenMPScheduleClauseModifier M2,
13323                                    SourceLocation M1Loc, SourceLocation M2Loc) {
13324   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13325     SmallVector<unsigned, 2> Excluded;
13326     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13327       Excluded.push_back(M2);
13328     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13329       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13330     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13331       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13332     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13333         << getListOfPossibleValues(OMPC_schedule,
13334                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13335                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13336                                    Excluded)
13337         << getOpenMPClauseName(OMPC_schedule);
13338     return true;
13339   }
13340   return false;
13341 }
13342 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)13343 OMPClause *Sema::ActOnOpenMPScheduleClause(
13344     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13345     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13346     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13347     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13348   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13349       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13350     return nullptr;
13351   // OpenMP, 2.7.1, Loop Construct, Restrictions
13352   // Either the monotonic modifier or the nonmonotonic modifier can be specified
13353   // but not both.
13354   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13355       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13356        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13357       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13358        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13359     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13360         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13361         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13362     return nullptr;
13363   }
13364   if (Kind == OMPC_SCHEDULE_unknown) {
13365     std::string Values;
13366     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13367       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13368       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13369                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13370                                        Exclude);
13371     } else {
13372       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13373                                        /*Last=*/OMPC_SCHEDULE_unknown);
13374     }
13375     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13376         << Values << getOpenMPClauseName(OMPC_schedule);
13377     return nullptr;
13378   }
13379   // OpenMP, 2.7.1, Loop Construct, Restrictions
13380   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13381   // schedule(guided).
13382   // OpenMP 5.0 does not have this restriction.
13383   if (LangOpts.OpenMP < 50 &&
13384       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13385        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13386       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13387     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13388          diag::err_omp_schedule_nonmonotonic_static);
13389     return nullptr;
13390   }
13391   Expr *ValExpr = ChunkSize;
13392   Stmt *HelperValStmt = nullptr;
13393   if (ChunkSize) {
13394     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13395         !ChunkSize->isInstantiationDependent() &&
13396         !ChunkSize->containsUnexpandedParameterPack()) {
13397       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13398       ExprResult Val =
13399           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13400       if (Val.isInvalid())
13401         return nullptr;
13402 
13403       ValExpr = Val.get();
13404 
13405       // OpenMP [2.7.1, Restrictions]
13406       //  chunk_size must be a loop invariant integer expression with a positive
13407       //  value.
13408       if (Optional<llvm::APSInt> Result =
13409               ValExpr->getIntegerConstantExpr(Context)) {
13410         if (Result->isSigned() && !Result->isStrictlyPositive()) {
13411           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13412               << "schedule" << 1 << ChunkSize->getSourceRange();
13413           return nullptr;
13414         }
13415       } else if (getOpenMPCaptureRegionForClause(
13416                      DSAStack->getCurrentDirective(), OMPC_schedule,
13417                      LangOpts.OpenMP) != OMPD_unknown &&
13418                  !CurContext->isDependentContext()) {
13419         ValExpr = MakeFullExpr(ValExpr).get();
13420         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13421         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13422         HelperValStmt = buildPreInits(Context, Captures);
13423       }
13424     }
13425   }
13426 
13427   return new (Context)
13428       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13429                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13430 }
13431 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)13432 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13433                                    SourceLocation StartLoc,
13434                                    SourceLocation EndLoc) {
13435   OMPClause *Res = nullptr;
13436   switch (Kind) {
13437   case OMPC_ordered:
13438     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13439     break;
13440   case OMPC_nowait:
13441     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13442     break;
13443   case OMPC_untied:
13444     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13445     break;
13446   case OMPC_mergeable:
13447     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13448     break;
13449   case OMPC_read:
13450     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13451     break;
13452   case OMPC_write:
13453     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13454     break;
13455   case OMPC_update:
13456     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13457     break;
13458   case OMPC_capture:
13459     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13460     break;
13461   case OMPC_seq_cst:
13462     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13463     break;
13464   case OMPC_acq_rel:
13465     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13466     break;
13467   case OMPC_acquire:
13468     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13469     break;
13470   case OMPC_release:
13471     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13472     break;
13473   case OMPC_relaxed:
13474     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13475     break;
13476   case OMPC_threads:
13477     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13478     break;
13479   case OMPC_simd:
13480     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13481     break;
13482   case OMPC_nogroup:
13483     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13484     break;
13485   case OMPC_unified_address:
13486     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13487     break;
13488   case OMPC_unified_shared_memory:
13489     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13490     break;
13491   case OMPC_reverse_offload:
13492     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13493     break;
13494   case OMPC_dynamic_allocators:
13495     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13496     break;
13497   case OMPC_destroy:
13498     Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13499     break;
13500   case OMPC_if:
13501   case OMPC_final:
13502   case OMPC_num_threads:
13503   case OMPC_safelen:
13504   case OMPC_simdlen:
13505   case OMPC_allocator:
13506   case OMPC_collapse:
13507   case OMPC_schedule:
13508   case OMPC_private:
13509   case OMPC_firstprivate:
13510   case OMPC_lastprivate:
13511   case OMPC_shared:
13512   case OMPC_reduction:
13513   case OMPC_task_reduction:
13514   case OMPC_in_reduction:
13515   case OMPC_linear:
13516   case OMPC_aligned:
13517   case OMPC_copyin:
13518   case OMPC_copyprivate:
13519   case OMPC_default:
13520   case OMPC_proc_bind:
13521   case OMPC_threadprivate:
13522   case OMPC_allocate:
13523   case OMPC_flush:
13524   case OMPC_depobj:
13525   case OMPC_depend:
13526   case OMPC_device:
13527   case OMPC_map:
13528   case OMPC_num_teams:
13529   case OMPC_thread_limit:
13530   case OMPC_priority:
13531   case OMPC_grainsize:
13532   case OMPC_num_tasks:
13533   case OMPC_hint:
13534   case OMPC_dist_schedule:
13535   case OMPC_defaultmap:
13536   case OMPC_unknown:
13537   case OMPC_uniform:
13538   case OMPC_to:
13539   case OMPC_from:
13540   case OMPC_use_device_ptr:
13541   case OMPC_use_device_addr:
13542   case OMPC_is_device_ptr:
13543   case OMPC_atomic_default_mem_order:
13544   case OMPC_device_type:
13545   case OMPC_match:
13546   case OMPC_nontemporal:
13547   case OMPC_order:
13548   case OMPC_detach:
13549   case OMPC_inclusive:
13550   case OMPC_exclusive:
13551   case OMPC_uses_allocators:
13552   case OMPC_affinity:
13553   default:
13554     llvm_unreachable("Clause is not allowed.");
13555   }
13556   return Res;
13557 }
13558 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)13559 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13560                                          SourceLocation EndLoc) {
13561   DSAStack->setNowaitRegion();
13562   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13563 }
13564 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)13565 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13566                                          SourceLocation EndLoc) {
13567   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13568 }
13569 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)13570 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13571                                             SourceLocation EndLoc) {
13572   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13573 }
13574 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)13575 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13576                                        SourceLocation EndLoc) {
13577   return new (Context) OMPReadClause(StartLoc, EndLoc);
13578 }
13579 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)13580 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13581                                         SourceLocation EndLoc) {
13582   return new (Context) OMPWriteClause(StartLoc, EndLoc);
13583 }
13584 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)13585 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13586                                          SourceLocation EndLoc) {
13587   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13588 }
13589 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)13590 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13591                                           SourceLocation EndLoc) {
13592   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13593 }
13594 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)13595 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13596                                          SourceLocation EndLoc) {
13597   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13598 }
13599 
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)13600 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13601                                          SourceLocation EndLoc) {
13602   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13603 }
13604 
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)13605 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13606                                           SourceLocation EndLoc) {
13607   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13608 }
13609 
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)13610 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13611                                           SourceLocation EndLoc) {
13612   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13613 }
13614 
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)13615 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13616                                           SourceLocation EndLoc) {
13617   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13618 }
13619 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)13620 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13621                                           SourceLocation EndLoc) {
13622   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13623 }
13624 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)13625 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13626                                        SourceLocation EndLoc) {
13627   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13628 }
13629 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)13630 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13631                                           SourceLocation EndLoc) {
13632   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13633 }
13634 
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)13635 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13636                                                  SourceLocation EndLoc) {
13637   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13638 }
13639 
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)13640 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13641                                                       SourceLocation EndLoc) {
13642   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13643 }
13644 
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)13645 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13646                                                  SourceLocation EndLoc) {
13647   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13648 }
13649 
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)13650 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13651                                                     SourceLocation EndLoc) {
13652   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13653 }
13654 
ActOnOpenMPDestroyClause(SourceLocation StartLoc,SourceLocation EndLoc)13655 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13656                                           SourceLocation EndLoc) {
13657   return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13658 }
13659 
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,Expr * DepModOrTailExpr,const OMPVarListLocTy & Locs,SourceLocation ColonLoc,CXXScopeSpec & ReductionOrMapperIdScopeSpec,DeclarationNameInfo & ReductionOrMapperId,int ExtraModifier,ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,bool IsMapTypeImplicit,SourceLocation ExtraModifierLoc,ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc)13660 OMPClause *Sema::ActOnOpenMPVarListClause(
13661     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13662     const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13663     CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13664     DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13665     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13666     ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13667     SourceLocation ExtraModifierLoc,
13668     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13669     ArrayRef<SourceLocation> MotionModifiersLoc) {
13670   SourceLocation StartLoc = Locs.StartLoc;
13671   SourceLocation LParenLoc = Locs.LParenLoc;
13672   SourceLocation EndLoc = Locs.EndLoc;
13673   OMPClause *Res = nullptr;
13674   switch (Kind) {
13675   case OMPC_private:
13676     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13677     break;
13678   case OMPC_firstprivate:
13679     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13680     break;
13681   case OMPC_lastprivate:
13682     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
13683            "Unexpected lastprivate modifier.");
13684     Res = ActOnOpenMPLastprivateClause(
13685         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13686         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13687     break;
13688   case OMPC_shared:
13689     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13690     break;
13691   case OMPC_reduction:
13692     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
13693            "Unexpected lastprivate modifier.");
13694     Res = ActOnOpenMPReductionClause(
13695         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13696         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13697         ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13698     break;
13699   case OMPC_task_reduction:
13700     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13701                                          EndLoc, ReductionOrMapperIdScopeSpec,
13702                                          ReductionOrMapperId);
13703     break;
13704   case OMPC_in_reduction:
13705     Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13706                                        EndLoc, ReductionOrMapperIdScopeSpec,
13707                                        ReductionOrMapperId);
13708     break;
13709   case OMPC_linear:
13710     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
13711            "Unexpected linear modifier.");
13712     Res = ActOnOpenMPLinearClause(
13713         VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13714         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13715         ColonLoc, EndLoc);
13716     break;
13717   case OMPC_aligned:
13718     Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13719                                    LParenLoc, ColonLoc, EndLoc);
13720     break;
13721   case OMPC_copyin:
13722     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13723     break;
13724   case OMPC_copyprivate:
13725     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13726     break;
13727   case OMPC_flush:
13728     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13729     break;
13730   case OMPC_depend:
13731     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
13732            "Unexpected depend modifier.");
13733     Res = ActOnOpenMPDependClause(
13734         DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13735         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13736     break;
13737   case OMPC_map:
13738     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
13739            "Unexpected map modifier.");
13740     Res = ActOnOpenMPMapClause(
13741         MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13742         ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13743         IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13744     break;
13745   case OMPC_to:
13746     Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13747                               ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13748                               ColonLoc, VarList, Locs);
13749     break;
13750   case OMPC_from:
13751     Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13752                                 ReductionOrMapperIdScopeSpec,
13753                                 ReductionOrMapperId, ColonLoc, VarList, Locs);
13754     break;
13755   case OMPC_use_device_ptr:
13756     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13757     break;
13758   case OMPC_use_device_addr:
13759     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13760     break;
13761   case OMPC_is_device_ptr:
13762     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13763     break;
13764   case OMPC_allocate:
13765     Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13766                                     LParenLoc, ColonLoc, EndLoc);
13767     break;
13768   case OMPC_nontemporal:
13769     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13770     break;
13771   case OMPC_inclusive:
13772     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13773     break;
13774   case OMPC_exclusive:
13775     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13776     break;
13777   case OMPC_affinity:
13778     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13779                                     DepModOrTailExpr, VarList);
13780     break;
13781   case OMPC_if:
13782   case OMPC_depobj:
13783   case OMPC_final:
13784   case OMPC_num_threads:
13785   case OMPC_safelen:
13786   case OMPC_simdlen:
13787   case OMPC_allocator:
13788   case OMPC_collapse:
13789   case OMPC_default:
13790   case OMPC_proc_bind:
13791   case OMPC_schedule:
13792   case OMPC_ordered:
13793   case OMPC_nowait:
13794   case OMPC_untied:
13795   case OMPC_mergeable:
13796   case OMPC_threadprivate:
13797   case OMPC_read:
13798   case OMPC_write:
13799   case OMPC_update:
13800   case OMPC_capture:
13801   case OMPC_seq_cst:
13802   case OMPC_acq_rel:
13803   case OMPC_acquire:
13804   case OMPC_release:
13805   case OMPC_relaxed:
13806   case OMPC_device:
13807   case OMPC_threads:
13808   case OMPC_simd:
13809   case OMPC_num_teams:
13810   case OMPC_thread_limit:
13811   case OMPC_priority:
13812   case OMPC_grainsize:
13813   case OMPC_nogroup:
13814   case OMPC_num_tasks:
13815   case OMPC_hint:
13816   case OMPC_dist_schedule:
13817   case OMPC_defaultmap:
13818   case OMPC_unknown:
13819   case OMPC_uniform:
13820   case OMPC_unified_address:
13821   case OMPC_unified_shared_memory:
13822   case OMPC_reverse_offload:
13823   case OMPC_dynamic_allocators:
13824   case OMPC_atomic_default_mem_order:
13825   case OMPC_device_type:
13826   case OMPC_match:
13827   case OMPC_order:
13828   case OMPC_destroy:
13829   case OMPC_detach:
13830   case OMPC_uses_allocators:
13831   default:
13832     llvm_unreachable("Clause is not allowed.");
13833   }
13834   return Res;
13835 }
13836 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)13837 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13838                                        ExprObjectKind OK, SourceLocation Loc) {
13839   ExprResult Res = BuildDeclRefExpr(
13840       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13841   if (!Res.isUsable())
13842     return ExprError();
13843   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13844     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13845     if (!Res.isUsable())
13846       return ExprError();
13847   }
13848   if (VK != VK_LValue && Res.get()->isGLValue()) {
13849     Res = DefaultLvalueConversion(Res.get());
13850     if (!Res.isUsable())
13851       return ExprError();
13852   }
13853   return Res;
13854 }
13855 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13856 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13857                                           SourceLocation StartLoc,
13858                                           SourceLocation LParenLoc,
13859                                           SourceLocation EndLoc) {
13860   SmallVector<Expr *, 8> Vars;
13861   SmallVector<Expr *, 8> PrivateCopies;
13862   for (Expr *RefExpr : VarList) {
13863     assert(RefExpr && "NULL expr in OpenMP private clause.");
13864     SourceLocation ELoc;
13865     SourceRange ERange;
13866     Expr *SimpleRefExpr = RefExpr;
13867     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13868     if (Res.second) {
13869       // It will be analyzed later.
13870       Vars.push_back(RefExpr);
13871       PrivateCopies.push_back(nullptr);
13872     }
13873     ValueDecl *D = Res.first;
13874     if (!D)
13875       continue;
13876 
13877     QualType Type = D->getType();
13878     auto *VD = dyn_cast<VarDecl>(D);
13879 
13880     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13881     //  A variable that appears in a private clause must not have an incomplete
13882     //  type or a reference type.
13883     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
13884       continue;
13885     Type = Type.getNonReferenceType();
13886 
13887     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13888     // A variable that is privatized must not have a const-qualified type
13889     // unless it is of class type with a mutable member. This restriction does
13890     // not apply to the firstprivate clause.
13891     //
13892     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
13893     // A variable that appears in a private clause must not have a
13894     // const-qualified type unless it is of class type with a mutable member.
13895     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
13896       continue;
13897 
13898     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13899     // in a Construct]
13900     //  Variables with the predetermined data-sharing attributes may not be
13901     //  listed in data-sharing attributes clauses, except for the cases
13902     //  listed below. For these exceptions only, listing a predetermined
13903     //  variable in a data-sharing attribute clause is allowed and overrides
13904     //  the variable's predetermined data-sharing attributes.
13905     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13906     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
13907       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13908                                           << getOpenMPClauseName(OMPC_private);
13909       reportOriginalDsa(*this, DSAStack, D, DVar);
13910       continue;
13911     }
13912 
13913     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13914     // Variably modified types are not supported for tasks.
13915     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13916         isOpenMPTaskingDirective(CurrDir)) {
13917       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13918           << getOpenMPClauseName(OMPC_private) << Type
13919           << getOpenMPDirectiveName(CurrDir);
13920       bool IsDecl =
13921           !VD ||
13922           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13923       Diag(D->getLocation(),
13924            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13925           << D;
13926       continue;
13927     }
13928 
13929     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13930     // A list item cannot appear in both a map clause and a data-sharing
13931     // attribute clause on the same construct
13932     //
13933     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13934     // A list item cannot appear in both a map clause and a data-sharing
13935     // attribute clause on the same construct unless the construct is a
13936     // combined construct.
13937     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
13938         CurrDir == OMPD_target) {
13939       OpenMPClauseKind ConflictKind;
13940       if (DSAStack->checkMappableExprComponentListsForDecl(
13941               VD, /*CurrentRegionOnly=*/true,
13942               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
13943                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
13944                 ConflictKind = WhereFoundClauseKind;
13945                 return true;
13946               })) {
13947         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13948             << getOpenMPClauseName(OMPC_private)
13949             << getOpenMPClauseName(ConflictKind)
13950             << getOpenMPDirectiveName(CurrDir);
13951         reportOriginalDsa(*this, DSAStack, D, DVar);
13952         continue;
13953       }
13954     }
13955 
13956     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
13957     //  A variable of class type (or array thereof) that appears in a private
13958     //  clause requires an accessible, unambiguous default constructor for the
13959     //  class type.
13960     // Generate helper private variable and initialize it with the default
13961     // value. The address of the original variable is replaced by the address of
13962     // the new private variable in CodeGen. This new variable is not added to
13963     // IdResolver, so the code in the OpenMP region uses original variable for
13964     // proper diagnostics.
13965     Type = Type.getUnqualifiedType();
13966     VarDecl *VDPrivate =
13967         buildVarDecl(*this, ELoc, Type, D->getName(),
13968                      D->hasAttrs() ? &D->getAttrs() : nullptr,
13969                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13970     ActOnUninitializedDecl(VDPrivate);
13971     if (VDPrivate->isInvalidDecl())
13972       continue;
13973     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13974         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13975 
13976     DeclRefExpr *Ref = nullptr;
13977     if (!VD && !CurContext->isDependentContext())
13978       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13979     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
13980     Vars.push_back((VD || CurContext->isDependentContext())
13981                        ? RefExpr->IgnoreParens()
13982                        : Ref);
13983     PrivateCopies.push_back(VDPrivateRefExpr);
13984   }
13985 
13986   if (Vars.empty())
13987     return nullptr;
13988 
13989   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13990                                   PrivateCopies);
13991 }
13992 
13993 namespace {
13994 class DiagsUninitializedSeveretyRAII {
13995 private:
13996   DiagnosticsEngine &Diags;
13997   SourceLocation SavedLoc;
13998   bool IsIgnored = false;
13999 
14000 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)14001   DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
14002                                  bool IsIgnored)
14003       : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
14004     if (!IsIgnored) {
14005       Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
14006                         /*Map*/ diag::Severity::Ignored, Loc);
14007     }
14008   }
~DiagsUninitializedSeveretyRAII()14009   ~DiagsUninitializedSeveretyRAII() {
14010     if (!IsIgnored)
14011       Diags.popMappings(SavedLoc);
14012   }
14013 };
14014 }
14015 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14016 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
14017                                                SourceLocation StartLoc,
14018                                                SourceLocation LParenLoc,
14019                                                SourceLocation EndLoc) {
14020   SmallVector<Expr *, 8> Vars;
14021   SmallVector<Expr *, 8> PrivateCopies;
14022   SmallVector<Expr *, 8> Inits;
14023   SmallVector<Decl *, 4> ExprCaptures;
14024   bool IsImplicitClause =
14025       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
14026   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
14027 
14028   for (Expr *RefExpr : VarList) {
14029     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
14030     SourceLocation ELoc;
14031     SourceRange ERange;
14032     Expr *SimpleRefExpr = RefExpr;
14033     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14034     if (Res.second) {
14035       // It will be analyzed later.
14036       Vars.push_back(RefExpr);
14037       PrivateCopies.push_back(nullptr);
14038       Inits.push_back(nullptr);
14039     }
14040     ValueDecl *D = Res.first;
14041     if (!D)
14042       continue;
14043 
14044     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
14045     QualType Type = D->getType();
14046     auto *VD = dyn_cast<VarDecl>(D);
14047 
14048     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14049     //  A variable that appears in a private clause must not have an incomplete
14050     //  type or a reference type.
14051     if (RequireCompleteType(ELoc, Type,
14052                             diag::err_omp_firstprivate_incomplete_type))
14053       continue;
14054     Type = Type.getNonReferenceType();
14055 
14056     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
14057     //  A variable of class type (or array thereof) that appears in a private
14058     //  clause requires an accessible, unambiguous copy constructor for the
14059     //  class type.
14060     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14061 
14062     // If an implicit firstprivate variable found it was checked already.
14063     DSAStackTy::DSAVarData TopDVar;
14064     if (!IsImplicitClause) {
14065       DSAStackTy::DSAVarData DVar =
14066           DSAStack->getTopDSA(D, /*FromParent=*/false);
14067       TopDVar = DVar;
14068       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14069       bool IsConstant = ElemType.isConstant(Context);
14070       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
14071       //  A list item that specifies a given variable may not appear in more
14072       // than one clause on the same directive, except that a variable may be
14073       //  specified in both firstprivate and lastprivate clauses.
14074       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14075       // A list item may appear in a firstprivate or lastprivate clause but not
14076       // both.
14077       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
14078           (isOpenMPDistributeDirective(CurrDir) ||
14079            DVar.CKind != OMPC_lastprivate) &&
14080           DVar.RefExpr) {
14081         Diag(ELoc, diag::err_omp_wrong_dsa)
14082             << getOpenMPClauseName(DVar.CKind)
14083             << getOpenMPClauseName(OMPC_firstprivate);
14084         reportOriginalDsa(*this, DSAStack, D, DVar);
14085         continue;
14086       }
14087 
14088       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14089       // in a Construct]
14090       //  Variables with the predetermined data-sharing attributes may not be
14091       //  listed in data-sharing attributes clauses, except for the cases
14092       //  listed below. For these exceptions only, listing a predetermined
14093       //  variable in a data-sharing attribute clause is allowed and overrides
14094       //  the variable's predetermined data-sharing attributes.
14095       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14096       // in a Construct, C/C++, p.2]
14097       //  Variables with const-qualified type having no mutable member may be
14098       //  listed in a firstprivate clause, even if they are static data members.
14099       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
14100           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
14101         Diag(ELoc, diag::err_omp_wrong_dsa)
14102             << getOpenMPClauseName(DVar.CKind)
14103             << getOpenMPClauseName(OMPC_firstprivate);
14104         reportOriginalDsa(*this, DSAStack, D, DVar);
14105         continue;
14106       }
14107 
14108       // OpenMP [2.9.3.4, Restrictions, p.2]
14109       //  A list item that is private within a parallel region must not appear
14110       //  in a firstprivate clause on a worksharing construct if any of the
14111       //  worksharing regions arising from the worksharing construct ever bind
14112       //  to any of the parallel regions arising from the parallel construct.
14113       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14114       // A list item that is private within a teams region must not appear in a
14115       // firstprivate clause on a distribute construct if any of the distribute
14116       // regions arising from the distribute construct ever bind to any of the
14117       // teams regions arising from the teams construct.
14118       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
14119       // A list item that appears in a reduction clause of a teams construct
14120       // must not appear in a firstprivate clause on a distribute construct if
14121       // any of the distribute regions arising from the distribute construct
14122       // ever bind to any of the teams regions arising from the teams construct.
14123       if ((isOpenMPWorksharingDirective(CurrDir) ||
14124            isOpenMPDistributeDirective(CurrDir)) &&
14125           !isOpenMPParallelDirective(CurrDir) &&
14126           !isOpenMPTeamsDirective(CurrDir)) {
14127         DVar = DSAStack->getImplicitDSA(D, true);
14128         if (DVar.CKind != OMPC_shared &&
14129             (isOpenMPParallelDirective(DVar.DKind) ||
14130              isOpenMPTeamsDirective(DVar.DKind) ||
14131              DVar.DKind == OMPD_unknown)) {
14132           Diag(ELoc, diag::err_omp_required_access)
14133               << getOpenMPClauseName(OMPC_firstprivate)
14134               << getOpenMPClauseName(OMPC_shared);
14135           reportOriginalDsa(*this, DSAStack, D, DVar);
14136           continue;
14137         }
14138       }
14139       // OpenMP [2.9.3.4, Restrictions, p.3]
14140       //  A list item that appears in a reduction clause of a parallel construct
14141       //  must not appear in a firstprivate clause on a worksharing or task
14142       //  construct if any of the worksharing or task regions arising from the
14143       //  worksharing or task construct ever bind to any of the parallel regions
14144       //  arising from the parallel construct.
14145       // OpenMP [2.9.3.4, Restrictions, p.4]
14146       //  A list item that appears in a reduction clause in worksharing
14147       //  construct must not appear in a firstprivate clause in a task construct
14148       //  encountered during execution of any of the worksharing regions arising
14149       //  from the worksharing construct.
14150       if (isOpenMPTaskingDirective(CurrDir)) {
14151         DVar = DSAStack->hasInnermostDSA(
14152             D,
14153             [](OpenMPClauseKind C, bool AppliedToPointee) {
14154               return C == OMPC_reduction && !AppliedToPointee;
14155             },
14156             [](OpenMPDirectiveKind K) {
14157               return isOpenMPParallelDirective(K) ||
14158                      isOpenMPWorksharingDirective(K) ||
14159                      isOpenMPTeamsDirective(K);
14160             },
14161             /*FromParent=*/true);
14162         if (DVar.CKind == OMPC_reduction &&
14163             (isOpenMPParallelDirective(DVar.DKind) ||
14164              isOpenMPWorksharingDirective(DVar.DKind) ||
14165              isOpenMPTeamsDirective(DVar.DKind))) {
14166           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14167               << getOpenMPDirectiveName(DVar.DKind);
14168           reportOriginalDsa(*this, DSAStack, D, DVar);
14169           continue;
14170         }
14171       }
14172 
14173       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14174       // A list item cannot appear in both a map clause and a data-sharing
14175       // attribute clause on the same construct
14176       //
14177       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14178       // A list item cannot appear in both a map clause and a data-sharing
14179       // attribute clause on the same construct unless the construct is a
14180       // combined construct.
14181       if ((LangOpts.OpenMP <= 45 &&
14182            isOpenMPTargetExecutionDirective(CurrDir)) ||
14183           CurrDir == OMPD_target) {
14184         OpenMPClauseKind ConflictKind;
14185         if (DSAStack->checkMappableExprComponentListsForDecl(
14186                 VD, /*CurrentRegionOnly=*/true,
14187                 [&ConflictKind](
14188                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
14189                     OpenMPClauseKind WhereFoundClauseKind) {
14190                   ConflictKind = WhereFoundClauseKind;
14191                   return true;
14192                 })) {
14193           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14194               << getOpenMPClauseName(OMPC_firstprivate)
14195               << getOpenMPClauseName(ConflictKind)
14196               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14197           reportOriginalDsa(*this, DSAStack, D, DVar);
14198           continue;
14199         }
14200       }
14201     }
14202 
14203     // Variably modified types are not supported for tasks.
14204     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14205         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
14206       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14207           << getOpenMPClauseName(OMPC_firstprivate) << Type
14208           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14209       bool IsDecl =
14210           !VD ||
14211           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14212       Diag(D->getLocation(),
14213            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14214           << D;
14215       continue;
14216     }
14217 
14218     Type = Type.getUnqualifiedType();
14219     VarDecl *VDPrivate =
14220         buildVarDecl(*this, ELoc, Type, D->getName(),
14221                      D->hasAttrs() ? &D->getAttrs() : nullptr,
14222                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14223     // Generate helper private variable and initialize it with the value of the
14224     // original variable. The address of the original variable is replaced by
14225     // the address of the new private variable in the CodeGen. This new variable
14226     // is not added to IdResolver, so the code in the OpenMP region uses
14227     // original variable for proper diagnostics and variable capturing.
14228     Expr *VDInitRefExpr = nullptr;
14229     // For arrays generate initializer for single element and replace it by the
14230     // original array element in CodeGen.
14231     if (Type->isArrayType()) {
14232       VarDecl *VDInit =
14233           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14234       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14235       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14236       ElemType = ElemType.getUnqualifiedType();
14237       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14238                                          ".firstprivate.temp");
14239       InitializedEntity Entity =
14240           InitializedEntity::InitializeVariable(VDInitTemp);
14241       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14242 
14243       InitializationSequence InitSeq(*this, Entity, Kind, Init);
14244       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14245       if (Result.isInvalid())
14246         VDPrivate->setInvalidDecl();
14247       else
14248         VDPrivate->setInit(Result.getAs<Expr>());
14249       // Remove temp variable declaration.
14250       Context.Deallocate(VDInitTemp);
14251     } else {
14252       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14253                                      ".firstprivate.temp");
14254       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14255                                        RefExpr->getExprLoc());
14256       AddInitializerToDecl(VDPrivate,
14257                            DefaultLvalueConversion(VDInitRefExpr).get(),
14258                            /*DirectInit=*/false);
14259     }
14260     if (VDPrivate->isInvalidDecl()) {
14261       if (IsImplicitClause) {
14262         Diag(RefExpr->getExprLoc(),
14263              diag::note_omp_task_predetermined_firstprivate_here);
14264       }
14265       continue;
14266     }
14267     CurContext->addDecl(VDPrivate);
14268     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14269         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14270         RefExpr->getExprLoc());
14271     DeclRefExpr *Ref = nullptr;
14272     if (!VD && !CurContext->isDependentContext()) {
14273       if (TopDVar.CKind == OMPC_lastprivate) {
14274         Ref = TopDVar.PrivateCopy;
14275       } else {
14276         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14277         if (!isOpenMPCapturedDecl(D))
14278           ExprCaptures.push_back(Ref->getDecl());
14279       }
14280     }
14281     if (!IsImplicitClause)
14282       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14283     Vars.push_back((VD || CurContext->isDependentContext())
14284                        ? RefExpr->IgnoreParens()
14285                        : Ref);
14286     PrivateCopies.push_back(VDPrivateRefExpr);
14287     Inits.push_back(VDInitRefExpr);
14288   }
14289 
14290   if (Vars.empty())
14291     return nullptr;
14292 
14293   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14294                                        Vars, PrivateCopies, Inits,
14295                                        buildPreInits(Context, ExprCaptures));
14296 }
14297 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14298 OMPClause *Sema::ActOnOpenMPLastprivateClause(
14299     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14300     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14301     SourceLocation LParenLoc, SourceLocation EndLoc) {
14302   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14303     assert(ColonLoc.isValid() && "Colon location must be valid.");
14304     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14305         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14306                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
14307         << getOpenMPClauseName(OMPC_lastprivate);
14308     return nullptr;
14309   }
14310 
14311   SmallVector<Expr *, 8> Vars;
14312   SmallVector<Expr *, 8> SrcExprs;
14313   SmallVector<Expr *, 8> DstExprs;
14314   SmallVector<Expr *, 8> AssignmentOps;
14315   SmallVector<Decl *, 4> ExprCaptures;
14316   SmallVector<Expr *, 4> ExprPostUpdates;
14317   for (Expr *RefExpr : VarList) {
14318     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14319     SourceLocation ELoc;
14320     SourceRange ERange;
14321     Expr *SimpleRefExpr = RefExpr;
14322     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14323     if (Res.second) {
14324       // It will be analyzed later.
14325       Vars.push_back(RefExpr);
14326       SrcExprs.push_back(nullptr);
14327       DstExprs.push_back(nullptr);
14328       AssignmentOps.push_back(nullptr);
14329     }
14330     ValueDecl *D = Res.first;
14331     if (!D)
14332       continue;
14333 
14334     QualType Type = D->getType();
14335     auto *VD = dyn_cast<VarDecl>(D);
14336 
14337     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14338     //  A variable that appears in a lastprivate clause must not have an
14339     //  incomplete type or a reference type.
14340     if (RequireCompleteType(ELoc, Type,
14341                             diag::err_omp_lastprivate_incomplete_type))
14342       continue;
14343     Type = Type.getNonReferenceType();
14344 
14345     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14346     // A variable that is privatized must not have a const-qualified type
14347     // unless it is of class type with a mutable member. This restriction does
14348     // not apply to the firstprivate clause.
14349     //
14350     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14351     // A variable that appears in a lastprivate clause must not have a
14352     // const-qualified type unless it is of class type with a mutable member.
14353     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14354       continue;
14355 
14356     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14357     // A list item that appears in a lastprivate clause with the conditional
14358     // modifier must be a scalar variable.
14359     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14360       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14361       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14362                                VarDecl::DeclarationOnly;
14363       Diag(D->getLocation(),
14364            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14365           << D;
14366       continue;
14367     }
14368 
14369     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14370     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14371     // in a Construct]
14372     //  Variables with the predetermined data-sharing attributes may not be
14373     //  listed in data-sharing attributes clauses, except for the cases
14374     //  listed below.
14375     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14376     // A list item may appear in a firstprivate or lastprivate clause but not
14377     // both.
14378     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14379     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14380         (isOpenMPDistributeDirective(CurrDir) ||
14381          DVar.CKind != OMPC_firstprivate) &&
14382         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14383       Diag(ELoc, diag::err_omp_wrong_dsa)
14384           << getOpenMPClauseName(DVar.CKind)
14385           << getOpenMPClauseName(OMPC_lastprivate);
14386       reportOriginalDsa(*this, DSAStack, D, DVar);
14387       continue;
14388     }
14389 
14390     // OpenMP [2.14.3.5, Restrictions, p.2]
14391     // A list item that is private within a parallel region, or that appears in
14392     // the reduction clause of a parallel construct, must not appear in a
14393     // lastprivate clause on a worksharing construct if any of the corresponding
14394     // worksharing regions ever binds to any of the corresponding parallel
14395     // regions.
14396     DSAStackTy::DSAVarData TopDVar = DVar;
14397     if (isOpenMPWorksharingDirective(CurrDir) &&
14398         !isOpenMPParallelDirective(CurrDir) &&
14399         !isOpenMPTeamsDirective(CurrDir)) {
14400       DVar = DSAStack->getImplicitDSA(D, true);
14401       if (DVar.CKind != OMPC_shared) {
14402         Diag(ELoc, diag::err_omp_required_access)
14403             << getOpenMPClauseName(OMPC_lastprivate)
14404             << getOpenMPClauseName(OMPC_shared);
14405         reportOriginalDsa(*this, DSAStack, D, DVar);
14406         continue;
14407       }
14408     }
14409 
14410     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14411     //  A variable of class type (or array thereof) that appears in a
14412     //  lastprivate clause requires an accessible, unambiguous default
14413     //  constructor for the class type, unless the list item is also specified
14414     //  in a firstprivate clause.
14415     //  A variable of class type (or array thereof) that appears in a
14416     //  lastprivate clause requires an accessible, unambiguous copy assignment
14417     //  operator for the class type.
14418     Type = Context.getBaseElementType(Type).getNonReferenceType();
14419     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14420                                   Type.getUnqualifiedType(), ".lastprivate.src",
14421                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
14422     DeclRefExpr *PseudoSrcExpr =
14423         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14424     VarDecl *DstVD =
14425         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14426                      D->hasAttrs() ? &D->getAttrs() : nullptr);
14427     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14428     // For arrays generate assignment operation for single element and replace
14429     // it by the original array element in CodeGen.
14430     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14431                                          PseudoDstExpr, PseudoSrcExpr);
14432     if (AssignmentOp.isInvalid())
14433       continue;
14434     AssignmentOp =
14435         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14436     if (AssignmentOp.isInvalid())
14437       continue;
14438 
14439     DeclRefExpr *Ref = nullptr;
14440     if (!VD && !CurContext->isDependentContext()) {
14441       if (TopDVar.CKind == OMPC_firstprivate) {
14442         Ref = TopDVar.PrivateCopy;
14443       } else {
14444         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14445         if (!isOpenMPCapturedDecl(D))
14446           ExprCaptures.push_back(Ref->getDecl());
14447       }
14448       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
14449           (!isOpenMPCapturedDecl(D) &&
14450            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14451         ExprResult RefRes = DefaultLvalueConversion(Ref);
14452         if (!RefRes.isUsable())
14453           continue;
14454         ExprResult PostUpdateRes =
14455             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14456                        RefRes.get());
14457         if (!PostUpdateRes.isUsable())
14458           continue;
14459         ExprPostUpdates.push_back(
14460             IgnoredValueConversions(PostUpdateRes.get()).get());
14461       }
14462     }
14463     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14464     Vars.push_back((VD || CurContext->isDependentContext())
14465                        ? RefExpr->IgnoreParens()
14466                        : Ref);
14467     SrcExprs.push_back(PseudoSrcExpr);
14468     DstExprs.push_back(PseudoDstExpr);
14469     AssignmentOps.push_back(AssignmentOp.get());
14470   }
14471 
14472   if (Vars.empty())
14473     return nullptr;
14474 
14475   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14476                                       Vars, SrcExprs, DstExprs, AssignmentOps,
14477                                       LPKind, LPKindLoc, ColonLoc,
14478                                       buildPreInits(Context, ExprCaptures),
14479                                       buildPostUpdate(*this, ExprPostUpdates));
14480 }
14481 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14482 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14483                                          SourceLocation StartLoc,
14484                                          SourceLocation LParenLoc,
14485                                          SourceLocation EndLoc) {
14486   SmallVector<Expr *, 8> Vars;
14487   for (Expr *RefExpr : VarList) {
14488     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14489     SourceLocation ELoc;
14490     SourceRange ERange;
14491     Expr *SimpleRefExpr = RefExpr;
14492     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14493     if (Res.second) {
14494       // It will be analyzed later.
14495       Vars.push_back(RefExpr);
14496     }
14497     ValueDecl *D = Res.first;
14498     if (!D)
14499       continue;
14500 
14501     auto *VD = dyn_cast<VarDecl>(D);
14502     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14503     // in a Construct]
14504     //  Variables with the predetermined data-sharing attributes may not be
14505     //  listed in data-sharing attributes clauses, except for the cases
14506     //  listed below. For these exceptions only, listing a predetermined
14507     //  variable in a data-sharing attribute clause is allowed and overrides
14508     //  the variable's predetermined data-sharing attributes.
14509     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14510     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14511         DVar.RefExpr) {
14512       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14513                                           << getOpenMPClauseName(OMPC_shared);
14514       reportOriginalDsa(*this, DSAStack, D, DVar);
14515       continue;
14516     }
14517 
14518     DeclRefExpr *Ref = nullptr;
14519     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14520       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14521     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14522     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14523                        ? RefExpr->IgnoreParens()
14524                        : Ref);
14525   }
14526 
14527   if (Vars.empty())
14528     return nullptr;
14529 
14530   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14531 }
14532 
14533 namespace {
14534 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14535   DSAStackTy *Stack;
14536 
14537 public:
VisitDeclRefExpr(DeclRefExpr * E)14538   bool VisitDeclRefExpr(DeclRefExpr *E) {
14539     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14540       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14541       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14542         return false;
14543       if (DVar.CKind != OMPC_unknown)
14544         return true;
14545       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14546           VD,
14547           [](OpenMPClauseKind C, bool AppliedToPointee) {
14548             return isOpenMPPrivate(C) && !AppliedToPointee;
14549           },
14550           [](OpenMPDirectiveKind) { return true; },
14551           /*FromParent=*/true);
14552       return DVarPrivate.CKind != OMPC_unknown;
14553     }
14554     return false;
14555   }
VisitStmt(Stmt * S)14556   bool VisitStmt(Stmt *S) {
14557     for (Stmt *Child : S->children()) {
14558       if (Child && Visit(Child))
14559         return true;
14560     }
14561     return false;
14562   }
DSARefChecker(DSAStackTy * S)14563   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14564 };
14565 } // namespace
14566 
14567 namespace {
14568 // Transform MemberExpression for specified FieldDecl of current class to
14569 // DeclRefExpr to specified OMPCapturedExprDecl.
14570 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14571   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14572   ValueDecl *Field = nullptr;
14573   DeclRefExpr *CapturedExpr = nullptr;
14574 
14575 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)14576   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14577       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14578 
TransformMemberExpr(MemberExpr * E)14579   ExprResult TransformMemberExpr(MemberExpr *E) {
14580     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14581         E->getMemberDecl() == Field) {
14582       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14583       return CapturedExpr;
14584     }
14585     return BaseTransform::TransformMemberExpr(E);
14586   }
getCapturedExpr()14587   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14588 };
14589 } // namespace
14590 
14591 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)14592 static T filterLookupForUDReductionAndMapper(
14593     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14594   for (U &Set : Lookups) {
14595     for (auto *D : Set) {
14596       if (T Res = Gen(cast<ValueDecl>(D)))
14597         return Res;
14598     }
14599   }
14600   return T();
14601 }
14602 
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)14603 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14604   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
14605 
14606   for (auto RD : D->redecls()) {
14607     // Don't bother with extra checks if we already know this one isn't visible.
14608     if (RD == D)
14609       continue;
14610 
14611     auto ND = cast<NamedDecl>(RD);
14612     if (LookupResult::isVisible(SemaRef, ND))
14613       return ND;
14614   }
14615 
14616   return nullptr;
14617 }
14618 
14619 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)14620 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14621                         SourceLocation Loc, QualType Ty,
14622                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14623   // Find all of the associated namespaces and classes based on the
14624   // arguments we have.
14625   Sema::AssociatedNamespaceSet AssociatedNamespaces;
14626   Sema::AssociatedClassSet AssociatedClasses;
14627   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14628   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14629                                              AssociatedClasses);
14630 
14631   // C++ [basic.lookup.argdep]p3:
14632   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
14633   //   and let Y be the lookup set produced by argument dependent
14634   //   lookup (defined as follows). If X contains [...] then Y is
14635   //   empty. Otherwise Y is the set of declarations found in the
14636   //   namespaces associated with the argument types as described
14637   //   below. The set of declarations found by the lookup of the name
14638   //   is the union of X and Y.
14639   //
14640   // Here, we compute Y and add its members to the overloaded
14641   // candidate set.
14642   for (auto *NS : AssociatedNamespaces) {
14643     //   When considering an associated namespace, the lookup is the
14644     //   same as the lookup performed when the associated namespace is
14645     //   used as a qualifier (3.4.3.2) except that:
14646     //
14647     //     -- Any using-directives in the associated namespace are
14648     //        ignored.
14649     //
14650     //     -- Any namespace-scope friend functions declared in
14651     //        associated classes are visible within their respective
14652     //        namespaces even if they are not visible during an ordinary
14653     //        lookup (11.4).
14654     DeclContext::lookup_result R = NS->lookup(Id.getName());
14655     for (auto *D : R) {
14656       auto *Underlying = D;
14657       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14658         Underlying = USD->getTargetDecl();
14659 
14660       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14661           !isa<OMPDeclareMapperDecl>(Underlying))
14662         continue;
14663 
14664       if (!SemaRef.isVisible(D)) {
14665         D = findAcceptableDecl(SemaRef, D);
14666         if (!D)
14667           continue;
14668         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14669           Underlying = USD->getTargetDecl();
14670       }
14671       Lookups.emplace_back();
14672       Lookups.back().addDecl(Underlying);
14673     }
14674   }
14675 }
14676 
14677 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)14678 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14679                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14680                          const DeclarationNameInfo &ReductionId, QualType Ty,
14681                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14682   if (ReductionIdScopeSpec.isInvalid())
14683     return ExprError();
14684   SmallVector<UnresolvedSet<8>, 4> Lookups;
14685   if (S) {
14686     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14687     Lookup.suppressDiagnostics();
14688     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14689       NamedDecl *D = Lookup.getRepresentativeDecl();
14690       do {
14691         S = S->getParent();
14692       } while (S && !S->isDeclScope(D));
14693       if (S)
14694         S = S->getParent();
14695       Lookups.emplace_back();
14696       Lookups.back().append(Lookup.begin(), Lookup.end());
14697       Lookup.clear();
14698     }
14699   } else if (auto *ULE =
14700                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14701     Lookups.push_back(UnresolvedSet<8>());
14702     Decl *PrevD = nullptr;
14703     for (NamedDecl *D : ULE->decls()) {
14704       if (D == PrevD)
14705         Lookups.push_back(UnresolvedSet<8>());
14706       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14707         Lookups.back().addDecl(DRD);
14708       PrevD = D;
14709     }
14710   }
14711   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14712       Ty->isInstantiationDependentType() ||
14713       Ty->containsUnexpandedParameterPack() ||
14714       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14715         return !D->isInvalidDecl() &&
14716                (D->getType()->isDependentType() ||
14717                 D->getType()->isInstantiationDependentType() ||
14718                 D->getType()->containsUnexpandedParameterPack());
14719       })) {
14720     UnresolvedSet<8> ResSet;
14721     for (const UnresolvedSet<8> &Set : Lookups) {
14722       if (Set.empty())
14723         continue;
14724       ResSet.append(Set.begin(), Set.end());
14725       // The last item marks the end of all declarations at the specified scope.
14726       ResSet.addDecl(Set[Set.size() - 1]);
14727     }
14728     return UnresolvedLookupExpr::Create(
14729         SemaRef.Context, /*NamingClass=*/nullptr,
14730         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14731         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14732   }
14733   // Lookup inside the classes.
14734   // C++ [over.match.oper]p3:
14735   //   For a unary operator @ with an operand of a type whose
14736   //   cv-unqualified version is T1, and for a binary operator @ with
14737   //   a left operand of a type whose cv-unqualified version is T1 and
14738   //   a right operand of a type whose cv-unqualified version is T2,
14739   //   three sets of candidate functions, designated member
14740   //   candidates, non-member candidates and built-in candidates, are
14741   //   constructed as follows:
14742   //     -- If T1 is a complete class type or a class currently being
14743   //        defined, the set of member candidates is the result of the
14744   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14745   //        the set of member candidates is empty.
14746   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14747   Lookup.suppressDiagnostics();
14748   if (const auto *TyRec = Ty->getAs<RecordType>()) {
14749     // Complete the type if it can be completed.
14750     // If the type is neither complete nor being defined, bail out now.
14751     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14752         TyRec->getDecl()->getDefinition()) {
14753       Lookup.clear();
14754       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14755       if (Lookup.empty()) {
14756         Lookups.emplace_back();
14757         Lookups.back().append(Lookup.begin(), Lookup.end());
14758       }
14759     }
14760   }
14761   // Perform ADL.
14762   if (SemaRef.getLangOpts().CPlusPlus)
14763     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14764   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14765           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14766             if (!D->isInvalidDecl() &&
14767                 SemaRef.Context.hasSameType(D->getType(), Ty))
14768               return D;
14769             return nullptr;
14770           }))
14771     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14772                                     VK_LValue, Loc);
14773   if (SemaRef.getLangOpts().CPlusPlus) {
14774     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14775             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14776               if (!D->isInvalidDecl() &&
14777                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14778                   !Ty.isMoreQualifiedThan(D->getType()))
14779                 return D;
14780               return nullptr;
14781             })) {
14782       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14783                          /*DetectVirtual=*/false);
14784       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14785         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14786                 VD->getType().getUnqualifiedType()))) {
14787           if (SemaRef.CheckBaseClassAccess(
14788                   Loc, VD->getType(), Ty, Paths.front(),
14789                   /*DiagID=*/0) != Sema::AR_inaccessible) {
14790             SemaRef.BuildBasePathArray(Paths, BasePath);
14791             return SemaRef.BuildDeclRefExpr(
14792                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14793           }
14794         }
14795       }
14796     }
14797   }
14798   if (ReductionIdScopeSpec.isSet()) {
14799     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14800         << Ty << Range;
14801     return ExprError();
14802   }
14803   return ExprEmpty();
14804 }
14805 
14806 namespace {
14807 /// Data for the reduction-based clauses.
14808 struct ReductionData {
14809   /// List of original reduction items.
14810   SmallVector<Expr *, 8> Vars;
14811   /// List of private copies of the reduction items.
14812   SmallVector<Expr *, 8> Privates;
14813   /// LHS expressions for the reduction_op expressions.
14814   SmallVector<Expr *, 8> LHSs;
14815   /// RHS expressions for the reduction_op expressions.
14816   SmallVector<Expr *, 8> RHSs;
14817   /// Reduction operation expression.
14818   SmallVector<Expr *, 8> ReductionOps;
14819   /// inscan copy operation expressions.
14820   SmallVector<Expr *, 8> InscanCopyOps;
14821   /// inscan copy temp array expressions for prefix sums.
14822   SmallVector<Expr *, 8> InscanCopyArrayTemps;
14823   /// inscan copy temp array element expressions for prefix sums.
14824   SmallVector<Expr *, 8> InscanCopyArrayElems;
14825   /// Taskgroup descriptors for the corresponding reduction items in
14826   /// in_reduction clauses.
14827   SmallVector<Expr *, 8> TaskgroupDescriptors;
14828   /// List of captures for clause.
14829   SmallVector<Decl *, 4> ExprCaptures;
14830   /// List of postupdate expressions.
14831   SmallVector<Expr *, 4> ExprPostUpdates;
14832   /// Reduction modifier.
14833   unsigned RedModifier = 0;
14834   ReductionData() = delete;
14835   /// Reserves required memory for the reduction data.
ReductionData__anon0bb9e2bb4811::ReductionData14836   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14837     Vars.reserve(Size);
14838     Privates.reserve(Size);
14839     LHSs.reserve(Size);
14840     RHSs.reserve(Size);
14841     ReductionOps.reserve(Size);
14842     if (RedModifier == OMPC_REDUCTION_inscan) {
14843       InscanCopyOps.reserve(Size);
14844       InscanCopyArrayTemps.reserve(Size);
14845       InscanCopyArrayElems.reserve(Size);
14846     }
14847     TaskgroupDescriptors.reserve(Size);
14848     ExprCaptures.reserve(Size);
14849     ExprPostUpdates.reserve(Size);
14850   }
14851   /// Stores reduction item and reduction operation only (required for dependent
14852   /// reduction item).
push__anon0bb9e2bb4811::ReductionData14853   void push(Expr *Item, Expr *ReductionOp) {
14854     Vars.emplace_back(Item);
14855     Privates.emplace_back(nullptr);
14856     LHSs.emplace_back(nullptr);
14857     RHSs.emplace_back(nullptr);
14858     ReductionOps.emplace_back(ReductionOp);
14859     TaskgroupDescriptors.emplace_back(nullptr);
14860     if (RedModifier == OMPC_REDUCTION_inscan) {
14861       InscanCopyOps.push_back(nullptr);
14862       InscanCopyArrayTemps.push_back(nullptr);
14863       InscanCopyArrayElems.push_back(nullptr);
14864     }
14865   }
14866   /// Stores reduction data.
push__anon0bb9e2bb4811::ReductionData14867   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
14868             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
14869             Expr *CopyArrayElem) {
14870     Vars.emplace_back(Item);
14871     Privates.emplace_back(Private);
14872     LHSs.emplace_back(LHS);
14873     RHSs.emplace_back(RHS);
14874     ReductionOps.emplace_back(ReductionOp);
14875     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
14876     if (RedModifier == OMPC_REDUCTION_inscan) {
14877       InscanCopyOps.push_back(CopyOp);
14878       InscanCopyArrayTemps.push_back(CopyArrayTemp);
14879       InscanCopyArrayElems.push_back(CopyArrayElem);
14880     } else {
14881       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
14882              CopyArrayElem == nullptr &&
14883              "Copy operation must be used for inscan reductions only.");
14884     }
14885   }
14886 };
14887 } // namespace
14888 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)14889 static bool checkOMPArraySectionConstantForReduction(
14890     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
14891     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
14892   const Expr *Length = OASE->getLength();
14893   if (Length == nullptr) {
14894     // For array sections of the form [1:] or [:], we would need to analyze
14895     // the lower bound...
14896     if (OASE->getColonLocFirst().isValid())
14897       return false;
14898 
14899     // This is an array subscript which has implicit length 1!
14900     SingleElement = true;
14901     ArraySizes.push_back(llvm::APSInt::get(1));
14902   } else {
14903     Expr::EvalResult Result;
14904     if (!Length->EvaluateAsInt(Result, Context))
14905       return false;
14906 
14907     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14908     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
14909     ArraySizes.push_back(ConstantLengthValue);
14910   }
14911 
14912   // Get the base of this array section and walk up from there.
14913   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
14914 
14915   // We require length = 1 for all array sections except the right-most to
14916   // guarantee that the memory region is contiguous and has no holes in it.
14917   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
14918     Length = TempOASE->getLength();
14919     if (Length == nullptr) {
14920       // For array sections of the form [1:] or [:], we would need to analyze
14921       // the lower bound...
14922       if (OASE->getColonLocFirst().isValid())
14923         return false;
14924 
14925       // This is an array subscript which has implicit length 1!
14926       ArraySizes.push_back(llvm::APSInt::get(1));
14927     } else {
14928       Expr::EvalResult Result;
14929       if (!Length->EvaluateAsInt(Result, Context))
14930         return false;
14931 
14932       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14933       if (ConstantLengthValue.getSExtValue() != 1)
14934         return false;
14935 
14936       ArraySizes.push_back(ConstantLengthValue);
14937     }
14938     Base = TempOASE->getBase()->IgnoreParenImpCasts();
14939   }
14940 
14941   // If we have a single element, we don't need to add the implicit lengths.
14942   if (!SingleElement) {
14943     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
14944       // Has implicit length 1!
14945       ArraySizes.push_back(llvm::APSInt::get(1));
14946       Base = TempASE->getBase()->IgnoreParenImpCasts();
14947     }
14948   }
14949 
14950   // This array section can be privatized as a single value or as a constant
14951   // sized array.
14952   return true;
14953 }
14954 
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)14955 static bool actOnOMPReductionKindClause(
14956     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
14957     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14958     SourceLocation ColonLoc, SourceLocation EndLoc,
14959     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14960     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
14961   DeclarationName DN = ReductionId.getName();
14962   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
14963   BinaryOperatorKind BOK = BO_Comma;
14964 
14965   ASTContext &Context = S.Context;
14966   // OpenMP [2.14.3.6, reduction clause]
14967   // C
14968   // reduction-identifier is either an identifier or one of the following
14969   // operators: +, -, *,  &, |, ^, && and ||
14970   // C++
14971   // reduction-identifier is either an id-expression or one of the following
14972   // operators: +, -, *, &, |, ^, && and ||
14973   switch (OOK) {
14974   case OO_Plus:
14975   case OO_Minus:
14976     BOK = BO_Add;
14977     break;
14978   case OO_Star:
14979     BOK = BO_Mul;
14980     break;
14981   case OO_Amp:
14982     BOK = BO_And;
14983     break;
14984   case OO_Pipe:
14985     BOK = BO_Or;
14986     break;
14987   case OO_Caret:
14988     BOK = BO_Xor;
14989     break;
14990   case OO_AmpAmp:
14991     BOK = BO_LAnd;
14992     break;
14993   case OO_PipePipe:
14994     BOK = BO_LOr;
14995     break;
14996   case OO_New:
14997   case OO_Delete:
14998   case OO_Array_New:
14999   case OO_Array_Delete:
15000   case OO_Slash:
15001   case OO_Percent:
15002   case OO_Tilde:
15003   case OO_Exclaim:
15004   case OO_Equal:
15005   case OO_Less:
15006   case OO_Greater:
15007   case OO_LessEqual:
15008   case OO_GreaterEqual:
15009   case OO_PlusEqual:
15010   case OO_MinusEqual:
15011   case OO_StarEqual:
15012   case OO_SlashEqual:
15013   case OO_PercentEqual:
15014   case OO_CaretEqual:
15015   case OO_AmpEqual:
15016   case OO_PipeEqual:
15017   case OO_LessLess:
15018   case OO_GreaterGreater:
15019   case OO_LessLessEqual:
15020   case OO_GreaterGreaterEqual:
15021   case OO_EqualEqual:
15022   case OO_ExclaimEqual:
15023   case OO_Spaceship:
15024   case OO_PlusPlus:
15025   case OO_MinusMinus:
15026   case OO_Comma:
15027   case OO_ArrowStar:
15028   case OO_Arrow:
15029   case OO_Call:
15030   case OO_Subscript:
15031   case OO_Conditional:
15032   case OO_Coawait:
15033   case NUM_OVERLOADED_OPERATORS:
15034     llvm_unreachable("Unexpected reduction identifier");
15035   case OO_None:
15036     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
15037       if (II->isStr("max"))
15038         BOK = BO_GT;
15039       else if (II->isStr("min"))
15040         BOK = BO_LT;
15041     }
15042     break;
15043   }
15044   SourceRange ReductionIdRange;
15045   if (ReductionIdScopeSpec.isValid())
15046     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
15047   else
15048     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
15049   ReductionIdRange.setEnd(ReductionId.getEndLoc());
15050 
15051   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
15052   bool FirstIter = true;
15053   for (Expr *RefExpr : VarList) {
15054     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
15055     // OpenMP [2.1, C/C++]
15056     //  A list item is a variable or array section, subject to the restrictions
15057     //  specified in Section 2.4 on page 42 and in each of the sections
15058     // describing clauses and directives for which a list appears.
15059     // OpenMP  [2.14.3.3, Restrictions, p.1]
15060     //  A variable that is part of another variable (as an array or
15061     //  structure element) cannot appear in a private clause.
15062     if (!FirstIter && IR != ER)
15063       ++IR;
15064     FirstIter = false;
15065     SourceLocation ELoc;
15066     SourceRange ERange;
15067     Expr *SimpleRefExpr = RefExpr;
15068     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
15069                               /*AllowArraySection=*/true);
15070     if (Res.second) {
15071       // Try to find 'declare reduction' corresponding construct before using
15072       // builtin/overloaded operators.
15073       QualType Type = Context.DependentTy;
15074       CXXCastPath BasePath;
15075       ExprResult DeclareReductionRef = buildDeclareReductionRef(
15076           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15077           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15078       Expr *ReductionOp = nullptr;
15079       if (S.CurContext->isDependentContext() &&
15080           (DeclareReductionRef.isUnset() ||
15081            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
15082         ReductionOp = DeclareReductionRef.get();
15083       // It will be analyzed later.
15084       RD.push(RefExpr, ReductionOp);
15085     }
15086     ValueDecl *D = Res.first;
15087     if (!D)
15088       continue;
15089 
15090     Expr *TaskgroupDescriptor = nullptr;
15091     QualType Type;
15092     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
15093     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
15094     if (ASE) {
15095       Type = ASE->getType().getNonReferenceType();
15096     } else if (OASE) {
15097       QualType BaseType =
15098           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15099       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15100         Type = ATy->getElementType();
15101       else
15102         Type = BaseType->getPointeeType();
15103       Type = Type.getNonReferenceType();
15104     } else {
15105       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
15106     }
15107     auto *VD = dyn_cast<VarDecl>(D);
15108 
15109     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15110     //  A variable that appears in a private clause must not have an incomplete
15111     //  type or a reference type.
15112     if (S.RequireCompleteType(ELoc, D->getType(),
15113                               diag::err_omp_reduction_incomplete_type))
15114       continue;
15115     // OpenMP [2.14.3.6, reduction clause, Restrictions]
15116     // A list item that appears in a reduction clause must not be
15117     // const-qualified.
15118     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
15119                                   /*AcceptIfMutable*/ false, ASE || OASE))
15120       continue;
15121 
15122     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
15123     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
15124     //  If a list-item is a reference type then it must bind to the same object
15125     //  for all threads of the team.
15126     if (!ASE && !OASE) {
15127       if (VD) {
15128         VarDecl *VDDef = VD->getDefinition();
15129         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15130           DSARefChecker Check(Stack);
15131           if (Check.Visit(VDDef->getInit())) {
15132             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15133                 << getOpenMPClauseName(ClauseKind) << ERange;
15134             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15135             continue;
15136           }
15137         }
15138       }
15139 
15140       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15141       // in a Construct]
15142       //  Variables with the predetermined data-sharing attributes may not be
15143       //  listed in data-sharing attributes clauses, except for the cases
15144       //  listed below. For these exceptions only, listing a predetermined
15145       //  variable in a data-sharing attribute clause is allowed and overrides
15146       //  the variable's predetermined data-sharing attributes.
15147       // OpenMP [2.14.3.6, Restrictions, p.3]
15148       //  Any number of reduction clauses can be specified on the directive,
15149       //  but a list item can appear only once in the reduction clauses for that
15150       //  directive.
15151       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15152       if (DVar.CKind == OMPC_reduction) {
15153         S.Diag(ELoc, diag::err_omp_once_referenced)
15154             << getOpenMPClauseName(ClauseKind);
15155         if (DVar.RefExpr)
15156           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15157         continue;
15158       }
15159       if (DVar.CKind != OMPC_unknown) {
15160         S.Diag(ELoc, diag::err_omp_wrong_dsa)
15161             << getOpenMPClauseName(DVar.CKind)
15162             << getOpenMPClauseName(OMPC_reduction);
15163         reportOriginalDsa(S, Stack, D, DVar);
15164         continue;
15165       }
15166 
15167       // OpenMP [2.14.3.6, Restrictions, p.1]
15168       //  A list item that appears in a reduction clause of a worksharing
15169       //  construct must be shared in the parallel regions to which any of the
15170       //  worksharing regions arising from the worksharing construct bind.
15171       if (isOpenMPWorksharingDirective(CurrDir) &&
15172           !isOpenMPParallelDirective(CurrDir) &&
15173           !isOpenMPTeamsDirective(CurrDir)) {
15174         DVar = Stack->getImplicitDSA(D, true);
15175         if (DVar.CKind != OMPC_shared) {
15176           S.Diag(ELoc, diag::err_omp_required_access)
15177               << getOpenMPClauseName(OMPC_reduction)
15178               << getOpenMPClauseName(OMPC_shared);
15179           reportOriginalDsa(S, Stack, D, DVar);
15180           continue;
15181         }
15182       }
15183     } else {
15184       // Threadprivates cannot be shared between threads, so dignose if the base
15185       // is a threadprivate variable.
15186       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15187       if (DVar.CKind == OMPC_threadprivate) {
15188         S.Diag(ELoc, diag::err_omp_wrong_dsa)
15189             << getOpenMPClauseName(DVar.CKind)
15190             << getOpenMPClauseName(OMPC_reduction);
15191         reportOriginalDsa(S, Stack, D, DVar);
15192         continue;
15193       }
15194     }
15195 
15196     // Try to find 'declare reduction' corresponding construct before using
15197     // builtin/overloaded operators.
15198     CXXCastPath BasePath;
15199     ExprResult DeclareReductionRef = buildDeclareReductionRef(
15200         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15201         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15202     if (DeclareReductionRef.isInvalid())
15203       continue;
15204     if (S.CurContext->isDependentContext() &&
15205         (DeclareReductionRef.isUnset() ||
15206          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15207       RD.push(RefExpr, DeclareReductionRef.get());
15208       continue;
15209     }
15210     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15211       // Not allowed reduction identifier is found.
15212       S.Diag(ReductionId.getBeginLoc(),
15213              diag::err_omp_unknown_reduction_identifier)
15214           << Type << ReductionIdRange;
15215       continue;
15216     }
15217 
15218     // OpenMP [2.14.3.6, reduction clause, Restrictions]
15219     // The type of a list item that appears in a reduction clause must be valid
15220     // for the reduction-identifier. For a max or min reduction in C, the type
15221     // of the list item must be an allowed arithmetic data type: char, int,
15222     // float, double, or _Bool, possibly modified with long, short, signed, or
15223     // unsigned. For a max or min reduction in C++, the type of the list item
15224     // must be an allowed arithmetic data type: char, wchar_t, int, float,
15225     // double, or bool, possibly modified with long, short, signed, or unsigned.
15226     if (DeclareReductionRef.isUnset()) {
15227       if ((BOK == BO_GT || BOK == BO_LT) &&
15228           !(Type->isScalarType() ||
15229             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15230         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15231             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15232         if (!ASE && !OASE) {
15233           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15234                                    VarDecl::DeclarationOnly;
15235           S.Diag(D->getLocation(),
15236                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15237               << D;
15238         }
15239         continue;
15240       }
15241       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15242           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15243         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15244             << getOpenMPClauseName(ClauseKind);
15245         if (!ASE && !OASE) {
15246           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15247                                    VarDecl::DeclarationOnly;
15248           S.Diag(D->getLocation(),
15249                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15250               << D;
15251         }
15252         continue;
15253       }
15254     }
15255 
15256     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15257     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15258                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
15259     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15260                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
15261     QualType PrivateTy = Type;
15262 
15263     // Try if we can determine constant lengths for all array sections and avoid
15264     // the VLA.
15265     bool ConstantLengthOASE = false;
15266     if (OASE) {
15267       bool SingleElement;
15268       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15269       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15270           Context, OASE, SingleElement, ArraySizes);
15271 
15272       // If we don't have a single element, we must emit a constant array type.
15273       if (ConstantLengthOASE && !SingleElement) {
15274         for (llvm::APSInt &Size : ArraySizes)
15275           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15276                                                    ArrayType::Normal,
15277                                                    /*IndexTypeQuals=*/0);
15278       }
15279     }
15280 
15281     if ((OASE && !ConstantLengthOASE) ||
15282         (!OASE && !ASE &&
15283          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15284       if (!Context.getTargetInfo().isVLASupported()) {
15285         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15286           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15287           S.Diag(ELoc, diag::note_vla_unsupported);
15288           continue;
15289         } else {
15290           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15291           S.targetDiag(ELoc, diag::note_vla_unsupported);
15292         }
15293       }
15294       // For arrays/array sections only:
15295       // Create pseudo array type for private copy. The size for this array will
15296       // be generated during codegen.
15297       // For array subscripts or single variables Private Ty is the same as Type
15298       // (type of the variable or single array element).
15299       PrivateTy = Context.getVariableArrayType(
15300           Type,
15301           new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15302           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15303     } else if (!ASE && !OASE &&
15304                Context.getAsArrayType(D->getType().getNonReferenceType())) {
15305       PrivateTy = D->getType().getNonReferenceType();
15306     }
15307     // Private copy.
15308     VarDecl *PrivateVD =
15309         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15310                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15311                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15312     // Add initializer for private variable.
15313     Expr *Init = nullptr;
15314     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15315     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15316     if (DeclareReductionRef.isUsable()) {
15317       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15318       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15319       if (DRD->getInitializer()) {
15320         S.ActOnUninitializedDecl(PrivateVD);
15321         Init = DRDRef;
15322         RHSVD->setInit(DRDRef);
15323         RHSVD->setInitStyle(VarDecl::CallInit);
15324       }
15325     } else {
15326       switch (BOK) {
15327       case BO_Add:
15328       case BO_Xor:
15329       case BO_Or:
15330       case BO_LOr:
15331         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15332         if (Type->isScalarType() || Type->isAnyComplexType())
15333           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15334         break;
15335       case BO_Mul:
15336       case BO_LAnd:
15337         if (Type->isScalarType() || Type->isAnyComplexType()) {
15338           // '*' and '&&' reduction ops - initializer is '1'.
15339           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15340         }
15341         break;
15342       case BO_And: {
15343         // '&' reduction op - initializer is '~0'.
15344         QualType OrigType = Type;
15345         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15346           Type = ComplexTy->getElementType();
15347         if (Type->isRealFloatingType()) {
15348           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15349               Context.getFloatTypeSemantics(Type),
15350               Context.getTypeSize(Type));
15351           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15352                                          Type, ELoc);
15353         } else if (Type->isScalarType()) {
15354           uint64_t Size = Context.getTypeSize(Type);
15355           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15356           llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15357           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15358         }
15359         if (Init && OrigType->isAnyComplexType()) {
15360           // Init = 0xFFFF + 0xFFFFi;
15361           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15362           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15363         }
15364         Type = OrigType;
15365         break;
15366       }
15367       case BO_LT:
15368       case BO_GT: {
15369         // 'min' reduction op - initializer is 'Largest representable number in
15370         // the reduction list item type'.
15371         // 'max' reduction op - initializer is 'Least representable number in
15372         // the reduction list item type'.
15373         if (Type->isIntegerType() || Type->isPointerType()) {
15374           bool IsSigned = Type->hasSignedIntegerRepresentation();
15375           uint64_t Size = Context.getTypeSize(Type);
15376           QualType IntTy =
15377               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15378           llvm::APInt InitValue =
15379               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15380                                         : llvm::APInt::getMinValue(Size)
15381                              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15382                                         : llvm::APInt::getMaxValue(Size);
15383           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15384           if (Type->isPointerType()) {
15385             // Cast to pointer type.
15386             ExprResult CastExpr = S.BuildCStyleCastExpr(
15387                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15388             if (CastExpr.isInvalid())
15389               continue;
15390             Init = CastExpr.get();
15391           }
15392         } else if (Type->isRealFloatingType()) {
15393           llvm::APFloat InitValue = llvm::APFloat::getLargest(
15394               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15395           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15396                                          Type, ELoc);
15397         }
15398         break;
15399       }
15400       case BO_PtrMemD:
15401       case BO_PtrMemI:
15402       case BO_MulAssign:
15403       case BO_Div:
15404       case BO_Rem:
15405       case BO_Sub:
15406       case BO_Shl:
15407       case BO_Shr:
15408       case BO_LE:
15409       case BO_GE:
15410       case BO_EQ:
15411       case BO_NE:
15412       case BO_Cmp:
15413       case BO_AndAssign:
15414       case BO_XorAssign:
15415       case BO_OrAssign:
15416       case BO_Assign:
15417       case BO_AddAssign:
15418       case BO_SubAssign:
15419       case BO_DivAssign:
15420       case BO_RemAssign:
15421       case BO_ShlAssign:
15422       case BO_ShrAssign:
15423       case BO_Comma:
15424         llvm_unreachable("Unexpected reduction operation");
15425       }
15426     }
15427     if (Init && DeclareReductionRef.isUnset()) {
15428       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15429       // Store initializer for single element in private copy. Will be used
15430       // during codegen.
15431       PrivateVD->setInit(RHSVD->getInit());
15432       PrivateVD->setInitStyle(RHSVD->getInitStyle());
15433     } else if (!Init) {
15434       S.ActOnUninitializedDecl(RHSVD);
15435       // Store initializer for single element in private copy. Will be used
15436       // during codegen.
15437       PrivateVD->setInit(RHSVD->getInit());
15438       PrivateVD->setInitStyle(RHSVD->getInitStyle());
15439     }
15440     if (RHSVD->isInvalidDecl())
15441       continue;
15442     if (!RHSVD->hasInit() &&
15443         (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15444       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15445           << Type << ReductionIdRange;
15446       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15447                                VarDecl::DeclarationOnly;
15448       S.Diag(D->getLocation(),
15449              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15450           << D;
15451       continue;
15452     }
15453     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15454     ExprResult ReductionOp;
15455     if (DeclareReductionRef.isUsable()) {
15456       QualType RedTy = DeclareReductionRef.get()->getType();
15457       QualType PtrRedTy = Context.getPointerType(RedTy);
15458       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15459       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15460       if (!BasePath.empty()) {
15461         LHS = S.DefaultLvalueConversion(LHS.get());
15462         RHS = S.DefaultLvalueConversion(RHS.get());
15463         LHS = ImplicitCastExpr::Create(
15464             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
15465             LHS.get()->getValueKind(), FPOptionsOverride());
15466         RHS = ImplicitCastExpr::Create(
15467             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
15468             RHS.get()->getValueKind(), FPOptionsOverride());
15469       }
15470       FunctionProtoType::ExtProtoInfo EPI;
15471       QualType Params[] = {PtrRedTy, PtrRedTy};
15472       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15473       auto *OVE = new (Context) OpaqueValueExpr(
15474           ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15475           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15476       Expr *Args[] = {LHS.get(), RHS.get()};
15477       ReductionOp =
15478           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15479                            S.CurFPFeatureOverrides());
15480     } else {
15481       ReductionOp = S.BuildBinOp(
15482           Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15483       if (ReductionOp.isUsable()) {
15484         if (BOK != BO_LT && BOK != BO_GT) {
15485           ReductionOp =
15486               S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15487                            BO_Assign, LHSDRE, ReductionOp.get());
15488         } else {
15489           auto *ConditionalOp = new (Context)
15490               ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15491                                   Type, VK_LValue, OK_Ordinary);
15492           ReductionOp =
15493               S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15494                            BO_Assign, LHSDRE, ConditionalOp);
15495         }
15496         if (ReductionOp.isUsable())
15497           ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15498                                               /*DiscardedValue*/ false);
15499       }
15500       if (!ReductionOp.isUsable())
15501         continue;
15502     }
15503 
15504     // Add copy operations for inscan reductions.
15505     // LHS = RHS;
15506     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15507     if (ClauseKind == OMPC_reduction &&
15508         RD.RedModifier == OMPC_REDUCTION_inscan) {
15509       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15510       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15511                                RHS.get());
15512       if (!CopyOpRes.isUsable())
15513         continue;
15514       CopyOpRes =
15515           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15516       if (!CopyOpRes.isUsable())
15517         continue;
15518       // For simd directive and simd-based directives in simd mode no need to
15519       // construct temp array, need just a single temp element.
15520       if (Stack->getCurrentDirective() == OMPD_simd ||
15521           (S.getLangOpts().OpenMPSimd &&
15522            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15523         VarDecl *TempArrayVD =
15524             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15525                          D->hasAttrs() ? &D->getAttrs() : nullptr);
15526         // Add a constructor to the temp decl.
15527         S.ActOnUninitializedDecl(TempArrayVD);
15528         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15529       } else {
15530         // Build temp array for prefix sum.
15531         auto *Dim = new (S.Context)
15532             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15533         QualType ArrayTy =
15534             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15535                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
15536         VarDecl *TempArrayVD =
15537             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15538                          D->hasAttrs() ? &D->getAttrs() : nullptr);
15539         // Add a constructor to the temp decl.
15540         S.ActOnUninitializedDecl(TempArrayVD);
15541         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15542         TempArrayElem =
15543             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15544         auto *Idx = new (S.Context)
15545             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15546         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15547                                                           ELoc, Idx, ELoc);
15548       }
15549     }
15550 
15551     // OpenMP [2.15.4.6, Restrictions, p.2]
15552     // A list item that appears in an in_reduction clause of a task construct
15553     // must appear in a task_reduction clause of a construct associated with a
15554     // taskgroup region that includes the participating task in its taskgroup
15555     // set. The construct associated with the innermost region that meets this
15556     // condition must specify the same reduction-identifier as the in_reduction
15557     // clause.
15558     if (ClauseKind == OMPC_in_reduction) {
15559       SourceRange ParentSR;
15560       BinaryOperatorKind ParentBOK;
15561       const Expr *ParentReductionOp = nullptr;
15562       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15563       DSAStackTy::DSAVarData ParentBOKDSA =
15564           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15565                                                   ParentBOKTD);
15566       DSAStackTy::DSAVarData ParentReductionOpDSA =
15567           Stack->getTopMostTaskgroupReductionData(
15568               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15569       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15570       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15571       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15572           (DeclareReductionRef.isUsable() && IsParentBOK) ||
15573           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15574         bool EmitError = true;
15575         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15576           llvm::FoldingSetNodeID RedId, ParentRedId;
15577           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15578           DeclareReductionRef.get()->Profile(RedId, Context,
15579                                              /*Canonical=*/true);
15580           EmitError = RedId != ParentRedId;
15581         }
15582         if (EmitError) {
15583           S.Diag(ReductionId.getBeginLoc(),
15584                  diag::err_omp_reduction_identifier_mismatch)
15585               << ReductionIdRange << RefExpr->getSourceRange();
15586           S.Diag(ParentSR.getBegin(),
15587                  diag::note_omp_previous_reduction_identifier)
15588               << ParentSR
15589               << (IsParentBOK ? ParentBOKDSA.RefExpr
15590                               : ParentReductionOpDSA.RefExpr)
15591                      ->getSourceRange();
15592           continue;
15593         }
15594       }
15595       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15596     }
15597 
15598     DeclRefExpr *Ref = nullptr;
15599     Expr *VarsExpr = RefExpr->IgnoreParens();
15600     if (!VD && !S.CurContext->isDependentContext()) {
15601       if (ASE || OASE) {
15602         TransformExprToCaptures RebuildToCapture(S, D);
15603         VarsExpr =
15604             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15605         Ref = RebuildToCapture.getCapturedExpr();
15606       } else {
15607         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15608       }
15609       if (!S.isOpenMPCapturedDecl(D)) {
15610         RD.ExprCaptures.emplace_back(Ref->getDecl());
15611         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15612           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15613           if (!RefRes.isUsable())
15614             continue;
15615           ExprResult PostUpdateRes =
15616               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15617                            RefRes.get());
15618           if (!PostUpdateRes.isUsable())
15619             continue;
15620           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15621               Stack->getCurrentDirective() == OMPD_taskgroup) {
15622             S.Diag(RefExpr->getExprLoc(),
15623                    diag::err_omp_reduction_non_addressable_expression)
15624                 << RefExpr->getSourceRange();
15625             continue;
15626           }
15627           RD.ExprPostUpdates.emplace_back(
15628               S.IgnoredValueConversions(PostUpdateRes.get()).get());
15629         }
15630       }
15631     }
15632     // All reduction items are still marked as reduction (to do not increase
15633     // code base size).
15634     unsigned Modifier = RD.RedModifier;
15635     // Consider task_reductions as reductions with task modifier. Required for
15636     // correct analysis of in_reduction clauses.
15637     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15638       Modifier = OMPC_REDUCTION_task;
15639     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
15640                   ASE || OASE);
15641     if (Modifier == OMPC_REDUCTION_task &&
15642         (CurrDir == OMPD_taskgroup ||
15643          ((isOpenMPParallelDirective(CurrDir) ||
15644            isOpenMPWorksharingDirective(CurrDir)) &&
15645           !isOpenMPSimdDirective(CurrDir)))) {
15646       if (DeclareReductionRef.isUsable())
15647         Stack->addTaskgroupReductionData(D, ReductionIdRange,
15648                                          DeclareReductionRef.get());
15649       else
15650         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15651     }
15652     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15653             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15654             TempArrayElem.get());
15655   }
15656   return RD.Vars.empty();
15657 }
15658 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15659 OMPClause *Sema::ActOnOpenMPReductionClause(
15660     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15661     SourceLocation StartLoc, SourceLocation LParenLoc,
15662     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15663     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15664     ArrayRef<Expr *> UnresolvedReductions) {
15665   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15666     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15667         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15668                                    /*Last=*/OMPC_REDUCTION_unknown)
15669         << getOpenMPClauseName(OMPC_reduction);
15670     return nullptr;
15671   }
15672   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15673   // A reduction clause with the inscan reduction-modifier may only appear on a
15674   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15675   // construct, a parallel worksharing-loop construct or a parallel
15676   // worksharing-loop SIMD construct.
15677   if (Modifier == OMPC_REDUCTION_inscan &&
15678       (DSAStack->getCurrentDirective() != OMPD_for &&
15679        DSAStack->getCurrentDirective() != OMPD_for_simd &&
15680        DSAStack->getCurrentDirective() != OMPD_simd &&
15681        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
15682        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
15683     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15684     return nullptr;
15685   }
15686 
15687   ReductionData RD(VarList.size(), Modifier);
15688   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
15689                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
15690                                   ReductionIdScopeSpec, ReductionId,
15691                                   UnresolvedReductions, RD))
15692     return nullptr;
15693 
15694   return OMPReductionClause::Create(
15695       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15696       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15697       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15698       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15699       buildPreInits(Context, RD.ExprCaptures),
15700       buildPostUpdate(*this, RD.ExprPostUpdates));
15701 }
15702 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15703 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15704     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15705     SourceLocation ColonLoc, SourceLocation EndLoc,
15706     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15707     ArrayRef<Expr *> UnresolvedReductions) {
15708   ReductionData RD(VarList.size());
15709   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
15710                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
15711                                   ReductionIdScopeSpec, ReductionId,
15712                                   UnresolvedReductions, RD))
15713     return nullptr;
15714 
15715   return OMPTaskReductionClause::Create(
15716       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15717       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15718       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15719       buildPreInits(Context, RD.ExprCaptures),
15720       buildPostUpdate(*this, RD.ExprPostUpdates));
15721 }
15722 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)15723 OMPClause *Sema::ActOnOpenMPInReductionClause(
15724     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15725     SourceLocation ColonLoc, SourceLocation EndLoc,
15726     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15727     ArrayRef<Expr *> UnresolvedReductions) {
15728   ReductionData RD(VarList.size());
15729   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
15730                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
15731                                   ReductionIdScopeSpec, ReductionId,
15732                                   UnresolvedReductions, RD))
15733     return nullptr;
15734 
15735   return OMPInReductionClause::Create(
15736       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15737       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15738       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15739       buildPreInits(Context, RD.ExprCaptures),
15740       buildPostUpdate(*this, RD.ExprPostUpdates));
15741 }
15742 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)15743 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15744                                      SourceLocation LinLoc) {
15745   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15746       LinKind == OMPC_LINEAR_unknown) {
15747     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15748     return true;
15749   }
15750   return false;
15751 }
15752 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)15753 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15754                                  OpenMPLinearClauseKind LinKind, QualType Type,
15755                                  bool IsDeclareSimd) {
15756   const auto *VD = dyn_cast_or_null<VarDecl>(D);
15757   // A variable must not have an incomplete type or a reference type.
15758   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15759     return true;
15760   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15761       !Type->isReferenceType()) {
15762     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15763         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15764     return true;
15765   }
15766   Type = Type.getNonReferenceType();
15767 
15768   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15769   // A variable that is privatized must not have a const-qualified type
15770   // unless it is of class type with a mutable member. This restriction does
15771   // not apply to the firstprivate clause, nor to the linear clause on
15772   // declarative directives (like declare simd).
15773   if (!IsDeclareSimd &&
15774       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15775     return true;
15776 
15777   // A list item must be of integral or pointer type.
15778   Type = Type.getUnqualifiedType().getCanonicalType();
15779   const auto *Ty = Type.getTypePtrOrNull();
15780   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15781               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15782     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15783     if (D) {
15784       bool IsDecl =
15785           !VD ||
15786           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15787       Diag(D->getLocation(),
15788            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15789           << D;
15790     }
15791     return true;
15792   }
15793   return false;
15794 }
15795 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)15796 OMPClause *Sema::ActOnOpenMPLinearClause(
15797     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15798     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15799     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15800   SmallVector<Expr *, 8> Vars;
15801   SmallVector<Expr *, 8> Privates;
15802   SmallVector<Expr *, 8> Inits;
15803   SmallVector<Decl *, 4> ExprCaptures;
15804   SmallVector<Expr *, 4> ExprPostUpdates;
15805   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15806     LinKind = OMPC_LINEAR_val;
15807   for (Expr *RefExpr : VarList) {
15808     assert(RefExpr && "NULL expr in OpenMP linear clause.");
15809     SourceLocation ELoc;
15810     SourceRange ERange;
15811     Expr *SimpleRefExpr = RefExpr;
15812     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15813     if (Res.second) {
15814       // It will be analyzed later.
15815       Vars.push_back(RefExpr);
15816       Privates.push_back(nullptr);
15817       Inits.push_back(nullptr);
15818     }
15819     ValueDecl *D = Res.first;
15820     if (!D)
15821       continue;
15822 
15823     QualType Type = D->getType();
15824     auto *VD = dyn_cast<VarDecl>(D);
15825 
15826     // OpenMP [2.14.3.7, linear clause]
15827     //  A list-item cannot appear in more than one linear clause.
15828     //  A list-item that appears in a linear clause cannot appear in any
15829     //  other data-sharing attribute clause.
15830     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15831     if (DVar.RefExpr) {
15832       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15833                                           << getOpenMPClauseName(OMPC_linear);
15834       reportOriginalDsa(*this, DSAStack, D, DVar);
15835       continue;
15836     }
15837 
15838     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15839       continue;
15840     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15841 
15842     // Build private copy of original var.
15843     VarDecl *Private =
15844         buildVarDecl(*this, ELoc, Type, D->getName(),
15845                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15846                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15847     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15848     // Build var to save initial value.
15849     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15850     Expr *InitExpr;
15851     DeclRefExpr *Ref = nullptr;
15852     if (!VD && !CurContext->isDependentContext()) {
15853       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15854       if (!isOpenMPCapturedDecl(D)) {
15855         ExprCaptures.push_back(Ref->getDecl());
15856         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15857           ExprResult RefRes = DefaultLvalueConversion(Ref);
15858           if (!RefRes.isUsable())
15859             continue;
15860           ExprResult PostUpdateRes =
15861               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
15862                          SimpleRefExpr, RefRes.get());
15863           if (!PostUpdateRes.isUsable())
15864             continue;
15865           ExprPostUpdates.push_back(
15866               IgnoredValueConversions(PostUpdateRes.get()).get());
15867         }
15868       }
15869     }
15870     if (LinKind == OMPC_LINEAR_uval)
15871       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
15872     else
15873       InitExpr = VD ? SimpleRefExpr : Ref;
15874     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
15875                          /*DirectInit=*/false);
15876     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
15877 
15878     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
15879     Vars.push_back((VD || CurContext->isDependentContext())
15880                        ? RefExpr->IgnoreParens()
15881                        : Ref);
15882     Privates.push_back(PrivateRef);
15883     Inits.push_back(InitRef);
15884   }
15885 
15886   if (Vars.empty())
15887     return nullptr;
15888 
15889   Expr *StepExpr = Step;
15890   Expr *CalcStepExpr = nullptr;
15891   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
15892       !Step->isInstantiationDependent() &&
15893       !Step->containsUnexpandedParameterPack()) {
15894     SourceLocation StepLoc = Step->getBeginLoc();
15895     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
15896     if (Val.isInvalid())
15897       return nullptr;
15898     StepExpr = Val.get();
15899 
15900     // Build var to save the step value.
15901     VarDecl *SaveVar =
15902         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
15903     ExprResult SaveRef =
15904         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
15905     ExprResult CalcStep =
15906         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
15907     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
15908 
15909     // Warn about zero linear step (it would be probably better specified as
15910     // making corresponding variables 'const').
15911     if (Optional<llvm::APSInt> Result =
15912             StepExpr->getIntegerConstantExpr(Context)) {
15913       if (!Result->isNegative() && !Result->isStrictlyPositive())
15914         Diag(StepLoc, diag::warn_omp_linear_step_zero)
15915             << Vars[0] << (Vars.size() > 1);
15916     } else if (CalcStep.isUsable()) {
15917       // Calculate the step beforehand instead of doing this on each iteration.
15918       // (This is not used if the number of iterations may be kfold-ed).
15919       CalcStepExpr = CalcStep.get();
15920     }
15921   }
15922 
15923   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
15924                                  ColonLoc, EndLoc, Vars, Privates, Inits,
15925                                  StepExpr, CalcStepExpr,
15926                                  buildPreInits(Context, ExprCaptures),
15927                                  buildPostUpdate(*this, ExprPostUpdates));
15928 }
15929 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)15930 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
15931                                      Expr *NumIterations, Sema &SemaRef,
15932                                      Scope *S, DSAStackTy *Stack) {
15933   // Walk the vars and build update/final expressions for the CodeGen.
15934   SmallVector<Expr *, 8> Updates;
15935   SmallVector<Expr *, 8> Finals;
15936   SmallVector<Expr *, 8> UsedExprs;
15937   Expr *Step = Clause.getStep();
15938   Expr *CalcStep = Clause.getCalcStep();
15939   // OpenMP [2.14.3.7, linear clause]
15940   // If linear-step is not specified it is assumed to be 1.
15941   if (!Step)
15942     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
15943   else if (CalcStep)
15944     Step = cast<BinaryOperator>(CalcStep)->getLHS();
15945   bool HasErrors = false;
15946   auto CurInit = Clause.inits().begin();
15947   auto CurPrivate = Clause.privates().begin();
15948   OpenMPLinearClauseKind LinKind = Clause.getModifier();
15949   for (Expr *RefExpr : Clause.varlists()) {
15950     SourceLocation ELoc;
15951     SourceRange ERange;
15952     Expr *SimpleRefExpr = RefExpr;
15953     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
15954     ValueDecl *D = Res.first;
15955     if (Res.second || !D) {
15956       Updates.push_back(nullptr);
15957       Finals.push_back(nullptr);
15958       HasErrors = true;
15959       continue;
15960     }
15961     auto &&Info = Stack->isLoopControlVariable(D);
15962     // OpenMP [2.15.11, distribute simd Construct]
15963     // A list item may not appear in a linear clause, unless it is the loop
15964     // iteration variable.
15965     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
15966         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
15967       SemaRef.Diag(ELoc,
15968                    diag::err_omp_linear_distribute_var_non_loop_iteration);
15969       Updates.push_back(nullptr);
15970       Finals.push_back(nullptr);
15971       HasErrors = true;
15972       continue;
15973     }
15974     Expr *InitExpr = *CurInit;
15975 
15976     // Build privatized reference to the current linear var.
15977     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
15978     Expr *CapturedRef;
15979     if (LinKind == OMPC_LINEAR_uval)
15980       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
15981     else
15982       CapturedRef =
15983           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
15984                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
15985                            /*RefersToCapture=*/true);
15986 
15987     // Build update: Var = InitExpr + IV * Step
15988     ExprResult Update;
15989     if (!Info.first)
15990       Update = buildCounterUpdate(
15991           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
15992           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
15993     else
15994       Update = *CurPrivate;
15995     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
15996                                          /*DiscardedValue*/ false);
15997 
15998     // Build final: Var = InitExpr + NumIterations * Step
15999     ExprResult Final;
16000     if (!Info.first)
16001       Final =
16002           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
16003                              InitExpr, NumIterations, Step, /*Subtract=*/false,
16004                              /*IsNonRectangularLB=*/false);
16005     else
16006       Final = *CurPrivate;
16007     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
16008                                         /*DiscardedValue*/ false);
16009 
16010     if (!Update.isUsable() || !Final.isUsable()) {
16011       Updates.push_back(nullptr);
16012       Finals.push_back(nullptr);
16013       UsedExprs.push_back(nullptr);
16014       HasErrors = true;
16015     } else {
16016       Updates.push_back(Update.get());
16017       Finals.push_back(Final.get());
16018       if (!Info.first)
16019         UsedExprs.push_back(SimpleRefExpr);
16020     }
16021     ++CurInit;
16022     ++CurPrivate;
16023   }
16024   if (Expr *S = Clause.getStep())
16025     UsedExprs.push_back(S);
16026   // Fill the remaining part with the nullptr.
16027   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
16028   Clause.setUpdates(Updates);
16029   Clause.setFinals(Finals);
16030   Clause.setUsedExprs(UsedExprs);
16031   return HasErrors;
16032 }
16033 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)16034 OMPClause *Sema::ActOnOpenMPAlignedClause(
16035     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
16036     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
16037   SmallVector<Expr *, 8> Vars;
16038   for (Expr *RefExpr : VarList) {
16039     assert(RefExpr && "NULL expr in OpenMP linear clause.");
16040     SourceLocation ELoc;
16041     SourceRange ERange;
16042     Expr *SimpleRefExpr = RefExpr;
16043     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16044     if (Res.second) {
16045       // It will be analyzed later.
16046       Vars.push_back(RefExpr);
16047     }
16048     ValueDecl *D = Res.first;
16049     if (!D)
16050       continue;
16051 
16052     QualType QType = D->getType();
16053     auto *VD = dyn_cast<VarDecl>(D);
16054 
16055     // OpenMP  [2.8.1, simd construct, Restrictions]
16056     // The type of list items appearing in the aligned clause must be
16057     // array, pointer, reference to array, or reference to pointer.
16058     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
16059     const Type *Ty = QType.getTypePtrOrNull();
16060     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
16061       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
16062           << QType << getLangOpts().CPlusPlus << ERange;
16063       bool IsDecl =
16064           !VD ||
16065           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16066       Diag(D->getLocation(),
16067            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16068           << D;
16069       continue;
16070     }
16071 
16072     // OpenMP  [2.8.1, simd construct, Restrictions]
16073     // A list-item cannot appear in more than one aligned clause.
16074     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
16075       Diag(ELoc, diag::err_omp_used_in_clause_twice)
16076           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
16077       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
16078           << getOpenMPClauseName(OMPC_aligned);
16079       continue;
16080     }
16081 
16082     DeclRefExpr *Ref = nullptr;
16083     if (!VD && isOpenMPCapturedDecl(D))
16084       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16085     Vars.push_back(DefaultFunctionArrayConversion(
16086                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
16087                        .get());
16088   }
16089 
16090   // OpenMP [2.8.1, simd construct, Description]
16091   // The parameter of the aligned clause, alignment, must be a constant
16092   // positive integer expression.
16093   // If no optional parameter is specified, implementation-defined default
16094   // alignments for SIMD instructions on the target platforms are assumed.
16095   if (Alignment != nullptr) {
16096     ExprResult AlignResult =
16097         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
16098     if (AlignResult.isInvalid())
16099       return nullptr;
16100     Alignment = AlignResult.get();
16101   }
16102   if (Vars.empty())
16103     return nullptr;
16104 
16105   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
16106                                   EndLoc, Vars, Alignment);
16107 }
16108 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16109 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
16110                                          SourceLocation StartLoc,
16111                                          SourceLocation LParenLoc,
16112                                          SourceLocation EndLoc) {
16113   SmallVector<Expr *, 8> Vars;
16114   SmallVector<Expr *, 8> SrcExprs;
16115   SmallVector<Expr *, 8> DstExprs;
16116   SmallVector<Expr *, 8> AssignmentOps;
16117   for (Expr *RefExpr : VarList) {
16118     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
16119     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16120       // It will be analyzed later.
16121       Vars.push_back(RefExpr);
16122       SrcExprs.push_back(nullptr);
16123       DstExprs.push_back(nullptr);
16124       AssignmentOps.push_back(nullptr);
16125       continue;
16126     }
16127 
16128     SourceLocation ELoc = RefExpr->getExprLoc();
16129     // OpenMP [2.1, C/C++]
16130     //  A list item is a variable name.
16131     // OpenMP  [2.14.4.1, Restrictions, p.1]
16132     //  A list item that appears in a copyin clause must be threadprivate.
16133     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
16134     if (!DE || !isa<VarDecl>(DE->getDecl())) {
16135       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
16136           << 0 << RefExpr->getSourceRange();
16137       continue;
16138     }
16139 
16140     Decl *D = DE->getDecl();
16141     auto *VD = cast<VarDecl>(D);
16142 
16143     QualType Type = VD->getType();
16144     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16145       // It will be analyzed later.
16146       Vars.push_back(DE);
16147       SrcExprs.push_back(nullptr);
16148       DstExprs.push_back(nullptr);
16149       AssignmentOps.push_back(nullptr);
16150       continue;
16151     }
16152 
16153     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16154     //  A list item that appears in a copyin clause must be threadprivate.
16155     if (!DSAStack->isThreadPrivate(VD)) {
16156       Diag(ELoc, diag::err_omp_required_access)
16157           << getOpenMPClauseName(OMPC_copyin)
16158           << getOpenMPDirectiveName(OMPD_threadprivate);
16159       continue;
16160     }
16161 
16162     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16163     //  A variable of class type (or array thereof) that appears in a
16164     //  copyin clause requires an accessible, unambiguous copy assignment
16165     //  operator for the class type.
16166     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16167     VarDecl *SrcVD =
16168         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16169                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16170     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16171         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16172     VarDecl *DstVD =
16173         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16174                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16175     DeclRefExpr *PseudoDstExpr =
16176         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16177     // For arrays generate assignment operation for single element and replace
16178     // it by the original array element in CodeGen.
16179     ExprResult AssignmentOp =
16180         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16181                    PseudoSrcExpr);
16182     if (AssignmentOp.isInvalid())
16183       continue;
16184     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16185                                        /*DiscardedValue*/ false);
16186     if (AssignmentOp.isInvalid())
16187       continue;
16188 
16189     DSAStack->addDSA(VD, DE, OMPC_copyin);
16190     Vars.push_back(DE);
16191     SrcExprs.push_back(PseudoSrcExpr);
16192     DstExprs.push_back(PseudoDstExpr);
16193     AssignmentOps.push_back(AssignmentOp.get());
16194   }
16195 
16196   if (Vars.empty())
16197     return nullptr;
16198 
16199   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16200                                  SrcExprs, DstExprs, AssignmentOps);
16201 }
16202 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16203 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16204                                               SourceLocation StartLoc,
16205                                               SourceLocation LParenLoc,
16206                                               SourceLocation EndLoc) {
16207   SmallVector<Expr *, 8> Vars;
16208   SmallVector<Expr *, 8> SrcExprs;
16209   SmallVector<Expr *, 8> DstExprs;
16210   SmallVector<Expr *, 8> AssignmentOps;
16211   for (Expr *RefExpr : VarList) {
16212     assert(RefExpr && "NULL expr in OpenMP linear clause.");
16213     SourceLocation ELoc;
16214     SourceRange ERange;
16215     Expr *SimpleRefExpr = RefExpr;
16216     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16217     if (Res.second) {
16218       // It will be analyzed later.
16219       Vars.push_back(RefExpr);
16220       SrcExprs.push_back(nullptr);
16221       DstExprs.push_back(nullptr);
16222       AssignmentOps.push_back(nullptr);
16223     }
16224     ValueDecl *D = Res.first;
16225     if (!D)
16226       continue;
16227 
16228     QualType Type = D->getType();
16229     auto *VD = dyn_cast<VarDecl>(D);
16230 
16231     // OpenMP [2.14.4.2, Restrictions, p.2]
16232     //  A list item that appears in a copyprivate clause may not appear in a
16233     //  private or firstprivate clause on the single construct.
16234     if (!VD || !DSAStack->isThreadPrivate(VD)) {
16235       DSAStackTy::DSAVarData DVar =
16236           DSAStack->getTopDSA(D, /*FromParent=*/false);
16237       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16238           DVar.RefExpr) {
16239         Diag(ELoc, diag::err_omp_wrong_dsa)
16240             << getOpenMPClauseName(DVar.CKind)
16241             << getOpenMPClauseName(OMPC_copyprivate);
16242         reportOriginalDsa(*this, DSAStack, D, DVar);
16243         continue;
16244       }
16245 
16246       // OpenMP [2.11.4.2, Restrictions, p.1]
16247       //  All list items that appear in a copyprivate clause must be either
16248       //  threadprivate or private in the enclosing context.
16249       if (DVar.CKind == OMPC_unknown) {
16250         DVar = DSAStack->getImplicitDSA(D, false);
16251         if (DVar.CKind == OMPC_shared) {
16252           Diag(ELoc, diag::err_omp_required_access)
16253               << getOpenMPClauseName(OMPC_copyprivate)
16254               << "threadprivate or private in the enclosing context";
16255           reportOriginalDsa(*this, DSAStack, D, DVar);
16256           continue;
16257         }
16258       }
16259     }
16260 
16261     // Variably modified types are not supported.
16262     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16263       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16264           << getOpenMPClauseName(OMPC_copyprivate) << Type
16265           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16266       bool IsDecl =
16267           !VD ||
16268           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16269       Diag(D->getLocation(),
16270            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16271           << D;
16272       continue;
16273     }
16274 
16275     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16276     //  A variable of class type (or array thereof) that appears in a
16277     //  copyin clause requires an accessible, unambiguous copy assignment
16278     //  operator for the class type.
16279     Type = Context.getBaseElementType(Type.getNonReferenceType())
16280                .getUnqualifiedType();
16281     VarDecl *SrcVD =
16282         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16283                      D->hasAttrs() ? &D->getAttrs() : nullptr);
16284     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16285     VarDecl *DstVD =
16286         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16287                      D->hasAttrs() ? &D->getAttrs() : nullptr);
16288     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16289     ExprResult AssignmentOp = BuildBinOp(
16290         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16291     if (AssignmentOp.isInvalid())
16292       continue;
16293     AssignmentOp =
16294         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16295     if (AssignmentOp.isInvalid())
16296       continue;
16297 
16298     // No need to mark vars as copyprivate, they are already threadprivate or
16299     // implicitly private.
16300     assert(VD || isOpenMPCapturedDecl(D));
16301     Vars.push_back(
16302         VD ? RefExpr->IgnoreParens()
16303            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16304     SrcExprs.push_back(PseudoSrcExpr);
16305     DstExprs.push_back(PseudoDstExpr);
16306     AssignmentOps.push_back(AssignmentOp.get());
16307   }
16308 
16309   if (Vars.empty())
16310     return nullptr;
16311 
16312   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16313                                       Vars, SrcExprs, DstExprs, AssignmentOps);
16314 }
16315 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16316 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16317                                         SourceLocation StartLoc,
16318                                         SourceLocation LParenLoc,
16319                                         SourceLocation EndLoc) {
16320   if (VarList.empty())
16321     return nullptr;
16322 
16323   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16324 }
16325 
16326 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)16327 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16328                            bool Diagnose = true) {
16329   QualType OMPDependT = Stack->getOMPDependT();
16330   if (!OMPDependT.isNull())
16331     return true;
16332   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16333   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16334   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16335     if (Diagnose)
16336       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16337     return false;
16338   }
16339   Stack->setOMPDependT(PT.get());
16340   return true;
16341 }
16342 
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16343 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16344                                          SourceLocation LParenLoc,
16345                                          SourceLocation EndLoc) {
16346   if (!Depobj)
16347     return nullptr;
16348 
16349   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
16350 
16351   // OpenMP 5.0, 2.17.10.1 depobj Construct
16352   // depobj is an lvalue expression of type omp_depend_t.
16353   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16354       !Depobj->isInstantiationDependent() &&
16355       !Depobj->containsUnexpandedParameterPack() &&
16356       (OMPDependTFound &&
16357        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
16358                                    /*CompareUnqualified=*/true))) {
16359     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16360         << 0 << Depobj->getType() << Depobj->getSourceRange();
16361   }
16362 
16363   if (!Depobj->isLValue()) {
16364     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16365         << 1 << Depobj->getSourceRange();
16366   }
16367 
16368   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16369 }
16370 
16371 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16372 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16373                               SourceLocation DepLoc, SourceLocation ColonLoc,
16374                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16375                               SourceLocation LParenLoc, SourceLocation EndLoc) {
16376   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
16377       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16378     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16379         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16380     return nullptr;
16381   }
16382   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
16383        DSAStack->getCurrentDirective() == OMPD_depobj) &&
16384       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16385        DepKind == OMPC_DEPEND_sink ||
16386        ((LangOpts.OpenMP < 50 ||
16387          DSAStack->getCurrentDirective() == OMPD_depobj) &&
16388         DepKind == OMPC_DEPEND_depobj))) {
16389     SmallVector<unsigned, 3> Except;
16390     Except.push_back(OMPC_DEPEND_source);
16391     Except.push_back(OMPC_DEPEND_sink);
16392     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
16393       Except.push_back(OMPC_DEPEND_depobj);
16394     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16395                                ? "depend modifier(iterator) or "
16396                                : "";
16397     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16398         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16399                                               /*Last=*/OMPC_DEPEND_unknown,
16400                                               Except)
16401         << getOpenMPClauseName(OMPC_depend);
16402     return nullptr;
16403   }
16404   if (DepModifier &&
16405       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16406     Diag(DepModifier->getExprLoc(),
16407          diag::err_omp_depend_sink_source_with_modifier);
16408     return nullptr;
16409   }
16410   if (DepModifier &&
16411       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16412     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16413 
16414   SmallVector<Expr *, 8> Vars;
16415   DSAStackTy::OperatorOffsetTy OpsOffs;
16416   llvm::APSInt DepCounter(/*BitWidth=*/32);
16417   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16418   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16419     if (const Expr *OrderedCountExpr =
16420             DSAStack->getParentOrderedRegionParam().first) {
16421       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16422       TotalDepCount.setIsUnsigned(/*Val=*/true);
16423     }
16424   }
16425   for (Expr *RefExpr : VarList) {
16426     assert(RefExpr && "NULL expr in OpenMP shared clause.");
16427     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16428       // It will be analyzed later.
16429       Vars.push_back(RefExpr);
16430       continue;
16431     }
16432 
16433     SourceLocation ELoc = RefExpr->getExprLoc();
16434     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16435     if (DepKind == OMPC_DEPEND_sink) {
16436       if (DSAStack->getParentOrderedRegionParam().first &&
16437           DepCounter >= TotalDepCount) {
16438         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16439         continue;
16440       }
16441       ++DepCounter;
16442       // OpenMP  [2.13.9, Summary]
16443       // depend(dependence-type : vec), where dependence-type is:
16444       // 'sink' and where vec is the iteration vector, which has the form:
16445       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16446       // where n is the value specified by the ordered clause in the loop
16447       // directive, xi denotes the loop iteration variable of the i-th nested
16448       // loop associated with the loop directive, and di is a constant
16449       // non-negative integer.
16450       if (CurContext->isDependentContext()) {
16451         // It will be analyzed later.
16452         Vars.push_back(RefExpr);
16453         continue;
16454       }
16455       SimpleExpr = SimpleExpr->IgnoreImplicit();
16456       OverloadedOperatorKind OOK = OO_None;
16457       SourceLocation OOLoc;
16458       Expr *LHS = SimpleExpr;
16459       Expr *RHS = nullptr;
16460       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16461         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16462         OOLoc = BO->getOperatorLoc();
16463         LHS = BO->getLHS()->IgnoreParenImpCasts();
16464         RHS = BO->getRHS()->IgnoreParenImpCasts();
16465       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16466         OOK = OCE->getOperator();
16467         OOLoc = OCE->getOperatorLoc();
16468         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16469         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16470       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16471         OOK = MCE->getMethodDecl()
16472                   ->getNameInfo()
16473                   .getName()
16474                   .getCXXOverloadedOperator();
16475         OOLoc = MCE->getCallee()->getExprLoc();
16476         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16477         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16478       }
16479       SourceLocation ELoc;
16480       SourceRange ERange;
16481       auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16482       if (Res.second) {
16483         // It will be analyzed later.
16484         Vars.push_back(RefExpr);
16485       }
16486       ValueDecl *D = Res.first;
16487       if (!D)
16488         continue;
16489 
16490       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16491         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16492         continue;
16493       }
16494       if (RHS) {
16495         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16496             RHS, OMPC_depend, /*StrictlyPositive=*/false);
16497         if (RHSRes.isInvalid())
16498           continue;
16499       }
16500       if (!CurContext->isDependentContext() &&
16501           DSAStack->getParentOrderedRegionParam().first &&
16502           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
16503         const ValueDecl *VD =
16504             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
16505         if (VD)
16506           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16507               << 1 << VD;
16508         else
16509           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16510         continue;
16511       }
16512       OpsOffs.emplace_back(RHS, OOK);
16513     } else {
16514       bool OMPDependTFound = LangOpts.OpenMP >= 50;
16515       if (OMPDependTFound)
16516         OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
16517                                          DepKind == OMPC_DEPEND_depobj);
16518       if (DepKind == OMPC_DEPEND_depobj) {
16519         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16520         // List items used in depend clauses with the depobj dependence type
16521         // must be expressions of the omp_depend_t type.
16522         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16523             !RefExpr->isInstantiationDependent() &&
16524             !RefExpr->containsUnexpandedParameterPack() &&
16525             (OMPDependTFound &&
16526              !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
16527                                              RefExpr->getType()))) {
16528           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16529               << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16530           continue;
16531         }
16532         if (!RefExpr->isLValue()) {
16533           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16534               << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16535           continue;
16536         }
16537       } else {
16538         // OpenMP 5.0 [2.17.11, Restrictions]
16539         // List items used in depend clauses cannot be zero-length array
16540         // sections.
16541         QualType ExprTy = RefExpr->getType().getNonReferenceType();
16542         const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16543         if (OASE) {
16544           QualType BaseType =
16545               OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16546           if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16547             ExprTy = ATy->getElementType();
16548           else
16549             ExprTy = BaseType->getPointeeType();
16550           ExprTy = ExprTy.getNonReferenceType();
16551           const Expr *Length = OASE->getLength();
16552           Expr::EvalResult Result;
16553           if (Length && !Length->isValueDependent() &&
16554               Length->EvaluateAsInt(Result, Context) &&
16555               Result.Val.getInt().isNullValue()) {
16556             Diag(ELoc,
16557                  diag::err_omp_depend_zero_length_array_section_not_allowed)
16558                 << SimpleExpr->getSourceRange();
16559             continue;
16560           }
16561         }
16562 
16563         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16564         // List items used in depend clauses with the in, out, inout or
16565         // mutexinoutset dependence types cannot be expressions of the
16566         // omp_depend_t type.
16567         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16568             !RefExpr->isInstantiationDependent() &&
16569             !RefExpr->containsUnexpandedParameterPack() &&
16570             (OMPDependTFound &&
16571              DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16572           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16573               << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16574               << RefExpr->getSourceRange();
16575           continue;
16576         }
16577 
16578         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16579         if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16580             (ASE && !ASE->getBase()->isTypeDependent() &&
16581              !ASE->getBase()
16582                   ->getType()
16583                   .getNonReferenceType()
16584                   ->isPointerType() &&
16585              !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16586           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16587               << (LangOpts.OpenMP >= 50 ? 1 : 0)
16588               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16589           continue;
16590         }
16591 
16592         ExprResult Res;
16593         {
16594           Sema::TentativeAnalysisScope Trap(*this);
16595           Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16596                                      RefExpr->IgnoreParenImpCasts());
16597         }
16598         if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16599             !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16600           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16601               << (LangOpts.OpenMP >= 50 ? 1 : 0)
16602               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16603           continue;
16604         }
16605       }
16606     }
16607     Vars.push_back(RefExpr->IgnoreParenImpCasts());
16608   }
16609 
16610   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16611       TotalDepCount > VarList.size() &&
16612       DSAStack->getParentOrderedRegionParam().first &&
16613       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
16614     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16615         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
16616   }
16617   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16618       Vars.empty())
16619     return nullptr;
16620 
16621   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16622                                     DepModifier, DepKind, DepLoc, ColonLoc,
16623                                     Vars, TotalDepCount.getZExtValue());
16624   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16625       DSAStack->isParentOrderedRegion())
16626     DSAStack->addDoacrossDependClause(C, OpsOffs);
16627   return C;
16628 }
16629 
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)16630 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16631                                          Expr *Device, SourceLocation StartLoc,
16632                                          SourceLocation LParenLoc,
16633                                          SourceLocation ModifierLoc,
16634                                          SourceLocation EndLoc) {
16635   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
16636          "Unexpected device modifier in OpenMP < 50.");
16637 
16638   bool ErrorFound = false;
16639   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16640     std::string Values =
16641         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16642     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16643         << Values << getOpenMPClauseName(OMPC_device);
16644     ErrorFound = true;
16645   }
16646 
16647   Expr *ValExpr = Device;
16648   Stmt *HelperValStmt = nullptr;
16649 
16650   // OpenMP [2.9.1, Restrictions]
16651   // The device expression must evaluate to a non-negative integer value.
16652   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16653                                           /*StrictlyPositive=*/false) ||
16654                ErrorFound;
16655   if (ErrorFound)
16656     return nullptr;
16657 
16658   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16659   OpenMPDirectiveKind CaptureRegion =
16660       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16661   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16662     ValExpr = MakeFullExpr(ValExpr).get();
16663     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16664     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16665     HelperValStmt = buildPreInits(Context, Captures);
16666   }
16667 
16668   return new (Context)
16669       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16670                       LParenLoc, ModifierLoc, EndLoc);
16671 }
16672 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)16673 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16674                               DSAStackTy *Stack, QualType QTy,
16675                               bool FullCheck = true) {
16676   NamedDecl *ND;
16677   if (QTy->isIncompleteType(&ND)) {
16678     SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16679     return false;
16680   }
16681   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16682       !QTy.isTriviallyCopyableType(SemaRef.Context))
16683     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16684   return true;
16685 }
16686 
16687 /// Return true if it can be proven that the provided array expression
16688 /// (array section or array subscript) does NOT specify the whole size of the
16689 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)16690 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16691                                                         const Expr *E,
16692                                                         QualType BaseQTy) {
16693   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16694 
16695   // If this is an array subscript, it refers to the whole size if the size of
16696   // the dimension is constant and equals 1. Also, an array section assumes the
16697   // format of an array subscript if no colon is used.
16698   if (isa<ArraySubscriptExpr>(E) ||
16699       (OASE && OASE->getColonLocFirst().isInvalid())) {
16700     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16701       return ATy->getSize().getSExtValue() != 1;
16702     // Size can't be evaluated statically.
16703     return false;
16704   }
16705 
16706   assert(OASE && "Expecting array section if not an array subscript.");
16707   const Expr *LowerBound = OASE->getLowerBound();
16708   const Expr *Length = OASE->getLength();
16709 
16710   // If there is a lower bound that does not evaluates to zero, we are not
16711   // covering the whole dimension.
16712   if (LowerBound) {
16713     Expr::EvalResult Result;
16714     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16715       return false; // Can't get the integer value as a constant.
16716 
16717     llvm::APSInt ConstLowerBound = Result.Val.getInt();
16718     if (ConstLowerBound.getSExtValue())
16719       return true;
16720   }
16721 
16722   // If we don't have a length we covering the whole dimension.
16723   if (!Length)
16724     return false;
16725 
16726   // If the base is a pointer, we don't have a way to get the size of the
16727   // pointee.
16728   if (BaseQTy->isPointerType())
16729     return false;
16730 
16731   // We can only check if the length is the same as the size of the dimension
16732   // if we have a constant array.
16733   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16734   if (!CATy)
16735     return false;
16736 
16737   Expr::EvalResult Result;
16738   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16739     return false; // Can't get the integer value as a constant.
16740 
16741   llvm::APSInt ConstLength = Result.Val.getInt();
16742   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16743 }
16744 
16745 // Return true if it can be proven that the provided array expression (array
16746 // section or array subscript) does NOT specify a single element of the array
16747 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)16748 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16749                                                         const Expr *E,
16750                                                         QualType BaseQTy) {
16751   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16752 
16753   // An array subscript always refer to a single element. Also, an array section
16754   // assumes the format of an array subscript if no colon is used.
16755   if (isa<ArraySubscriptExpr>(E) ||
16756       (OASE && OASE->getColonLocFirst().isInvalid()))
16757     return false;
16758 
16759   assert(OASE && "Expecting array section if not an array subscript.");
16760   const Expr *Length = OASE->getLength();
16761 
16762   // If we don't have a length we have to check if the array has unitary size
16763   // for this dimension. Also, we should always expect a length if the base type
16764   // is pointer.
16765   if (!Length) {
16766     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16767       return ATy->getSize().getSExtValue() != 1;
16768     // We cannot assume anything.
16769     return false;
16770   }
16771 
16772   // Check if the length evaluates to 1.
16773   Expr::EvalResult Result;
16774   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16775     return false; // Can't get the integer value as a constant.
16776 
16777   llvm::APSInt ConstLength = Result.Val.getInt();
16778   return ConstLength.getSExtValue() != 1;
16779 }
16780 
16781 // The base of elements of list in a map clause have to be either:
16782 //  - a reference to variable or field.
16783 //  - a member expression.
16784 //  - an array expression.
16785 //
16786 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16787 // reference to 'r'.
16788 //
16789 // If we have:
16790 //
16791 // struct SS {
16792 //   Bla S;
16793 //   foo() {
16794 //     #pragma omp target map (S.Arr[:12]);
16795 //   }
16796 // }
16797 //
16798 // We want to retrieve the member expression 'this->S';
16799 
16800 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16801 //  If a list item is an array section, it must specify contiguous storage.
16802 //
16803 // For this restriction it is sufficient that we make sure only references
16804 // to variables or fields and array expressions, and that no array sections
16805 // exist except in the rightmost expression (unless they cover the whole
16806 // dimension of the array). E.g. these would be invalid:
16807 //
16808 //   r.ArrS[3:5].Arr[6:7]
16809 //
16810 //   r.ArrS[3:5].x
16811 //
16812 // but these would be valid:
16813 //   r.ArrS[3].Arr[6:7]
16814 //
16815 //   r.ArrS[3].x
16816 namespace {
16817 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16818   Sema &SemaRef;
16819   OpenMPClauseKind CKind = OMPC_unknown;
16820   OpenMPDirectiveKind DKind = OMPD_unknown;
16821   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16822   bool IsNonContiguous = false;
16823   bool NoDiagnose = false;
16824   const Expr *RelevantExpr = nullptr;
16825   bool AllowUnitySizeArraySection = true;
16826   bool AllowWholeSizeArraySection = true;
16827   bool AllowAnotherPtr = true;
16828   SourceLocation ELoc;
16829   SourceRange ERange;
16830 
emitErrorMsg()16831   void emitErrorMsg() {
16832     // If nothing else worked, this is not a valid map clause expression.
16833     if (SemaRef.getLangOpts().OpenMP < 50) {
16834       SemaRef.Diag(ELoc,
16835                    diag::err_omp_expected_named_var_member_or_array_expression)
16836           << ERange;
16837     } else {
16838       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16839           << getOpenMPClauseName(CKind) << ERange;
16840     }
16841   }
16842 
16843 public:
VisitDeclRefExpr(DeclRefExpr * DRE)16844   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16845     if (!isa<VarDecl>(DRE->getDecl())) {
16846       emitErrorMsg();
16847       return false;
16848     }
16849     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16850     RelevantExpr = DRE;
16851     // Record the component.
16852     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
16853     return true;
16854   }
16855 
VisitMemberExpr(MemberExpr * ME)16856   bool VisitMemberExpr(MemberExpr *ME) {
16857     Expr *E = ME;
16858     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16859 
16860     if (isa<CXXThisExpr>(BaseE)) {
16861       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16862       // We found a base expression: this->Val.
16863       RelevantExpr = ME;
16864     } else {
16865       E = BaseE;
16866     }
16867 
16868     if (!isa<FieldDecl>(ME->getMemberDecl())) {
16869       if (!NoDiagnose) {
16870         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
16871           << ME->getSourceRange();
16872         return false;
16873       }
16874       if (RelevantExpr)
16875         return false;
16876       return Visit(E);
16877     }
16878 
16879     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
16880 
16881     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
16882     //  A bit-field cannot appear in a map clause.
16883     //
16884     if (FD->isBitField()) {
16885       if (!NoDiagnose) {
16886         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
16887           << ME->getSourceRange() << getOpenMPClauseName(CKind);
16888         return false;
16889       }
16890       if (RelevantExpr)
16891         return false;
16892       return Visit(E);
16893     }
16894 
16895     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16896     //  If the type of a list item is a reference to a type T then the type
16897     //  will be considered to be T for all purposes of this clause.
16898     QualType CurType = BaseE->getType().getNonReferenceType();
16899 
16900     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
16901     //  A list item cannot be a variable that is a member of a structure with
16902     //  a union type.
16903     //
16904     if (CurType->isUnionType()) {
16905       if (!NoDiagnose) {
16906         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
16907           << ME->getSourceRange();
16908         return false;
16909       }
16910       return RelevantExpr || Visit(E);
16911     }
16912 
16913     // If we got a member expression, we should not expect any array section
16914     // before that:
16915     //
16916     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
16917     //  If a list item is an element of a structure, only the rightmost symbol
16918     //  of the variable reference can be an array section.
16919     //
16920     AllowUnitySizeArraySection = false;
16921     AllowWholeSizeArraySection = false;
16922 
16923     // Record the component.
16924     Components.emplace_back(ME, FD, IsNonContiguous);
16925     return RelevantExpr || Visit(E);
16926   }
16927 
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)16928   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
16929     Expr *E = AE->getBase()->IgnoreParenImpCasts();
16930 
16931     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
16932       if (!NoDiagnose) {
16933         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16934           << 0 << AE->getSourceRange();
16935         return false;
16936       }
16937       return RelevantExpr || Visit(E);
16938     }
16939 
16940     // If we got an array subscript that express the whole dimension we
16941     // can have any array expressions before. If it only expressing part of
16942     // the dimension, we can only have unitary-size array expressions.
16943     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
16944                                                     E->getType()))
16945       AllowWholeSizeArraySection = false;
16946 
16947     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
16948       Expr::EvalResult Result;
16949       if (!AE->getIdx()->isValueDependent() &&
16950           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
16951           !Result.Val.getInt().isNullValue()) {
16952         SemaRef.Diag(AE->getIdx()->getExprLoc(),
16953                      diag::err_omp_invalid_map_this_expr);
16954         SemaRef.Diag(AE->getIdx()->getExprLoc(),
16955                      diag::note_omp_invalid_subscript_on_this_ptr_map);
16956       }
16957       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16958       RelevantExpr = TE;
16959     }
16960 
16961     // Record the component - we don't have any declaration associated.
16962     Components.emplace_back(AE, nullptr, IsNonContiguous);
16963 
16964     return RelevantExpr || Visit(E);
16965   }
16966 
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)16967   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
16968     assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
16969     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16970     QualType CurType =
16971       OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16972 
16973     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16974     //  If the type of a list item is a reference to a type T then the type
16975     //  will be considered to be T for all purposes of this clause.
16976     if (CurType->isReferenceType())
16977       CurType = CurType->getPointeeType();
16978 
16979     bool IsPointer = CurType->isAnyPointerType();
16980 
16981     if (!IsPointer && !CurType->isArrayType()) {
16982       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16983         << 0 << OASE->getSourceRange();
16984       return false;
16985     }
16986 
16987     bool NotWhole =
16988       checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
16989     bool NotUnity =
16990       checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
16991 
16992     if (AllowWholeSizeArraySection) {
16993       // Any array section is currently allowed. Allowing a whole size array
16994       // section implies allowing a unity array section as well.
16995       //
16996       // If this array section refers to the whole dimension we can still
16997       // accept other array sections before this one, except if the base is a
16998       // pointer. Otherwise, only unitary sections are accepted.
16999       if (NotWhole || IsPointer)
17000         AllowWholeSizeArraySection = false;
17001     } else if (DKind == OMPD_target_update &&
17002                SemaRef.getLangOpts().OpenMP >= 50) {
17003       if (IsPointer && !AllowAnotherPtr)
17004         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
17005             << /*array of unknown bound */ 1;
17006       else
17007         IsNonContiguous = true;
17008     } else if (AllowUnitySizeArraySection && NotUnity) {
17009       // A unity or whole array section is not allowed and that is not
17010       // compatible with the properties of the current array section.
17011       SemaRef.Diag(
17012         ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
17013         << OASE->getSourceRange();
17014       return false;
17015     }
17016 
17017     if (IsPointer)
17018       AllowAnotherPtr = false;
17019 
17020     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
17021       Expr::EvalResult ResultR;
17022       Expr::EvalResult ResultL;
17023       if (!OASE->getLength()->isValueDependent() &&
17024           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
17025           !ResultR.Val.getInt().isOneValue()) {
17026         SemaRef.Diag(OASE->getLength()->getExprLoc(),
17027                      diag::err_omp_invalid_map_this_expr);
17028         SemaRef.Diag(OASE->getLength()->getExprLoc(),
17029                      diag::note_omp_invalid_length_on_this_ptr_mapping);
17030       }
17031       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
17032           OASE->getLowerBound()->EvaluateAsInt(ResultL,
17033                                                SemaRef.getASTContext()) &&
17034           !ResultL.Val.getInt().isNullValue()) {
17035         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17036                      diag::err_omp_invalid_map_this_expr);
17037         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
17038                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
17039       }
17040       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17041       RelevantExpr = TE;
17042     }
17043 
17044     // Record the component - we don't have any declaration associated.
17045     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
17046     return RelevantExpr || Visit(E);
17047   }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)17048   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
17049     Expr *Base = E->getBase();
17050 
17051     // Record the component - we don't have any declaration associated.
17052     Components.emplace_back(E, nullptr, IsNonContiguous);
17053 
17054     return Visit(Base->IgnoreParenImpCasts());
17055   }
17056 
VisitUnaryOperator(UnaryOperator * UO)17057   bool VisitUnaryOperator(UnaryOperator *UO) {
17058     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
17059         UO->getOpcode() != UO_Deref) {
17060       emitErrorMsg();
17061       return false;
17062     }
17063     if (!RelevantExpr) {
17064       // Record the component if haven't found base decl.
17065       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
17066     }
17067     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
17068   }
VisitBinaryOperator(BinaryOperator * BO)17069   bool VisitBinaryOperator(BinaryOperator *BO) {
17070     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
17071       emitErrorMsg();
17072       return false;
17073     }
17074 
17075     // Pointer arithmetic is the only thing we expect to happen here so after we
17076     // make sure the binary operator is a pointer type, the we only thing need
17077     // to to is to visit the subtree that has the same type as root (so that we
17078     // know the other subtree is just an offset)
17079     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
17080     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
17081     Components.emplace_back(BO, nullptr, false);
17082     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
17083             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
17084            "Either LHS or RHS have base decl inside");
17085     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
17086       return RelevantExpr || Visit(LE);
17087     return RelevantExpr || Visit(RE);
17088   }
VisitCXXThisExpr(CXXThisExpr * CTE)17089   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
17090     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17091     RelevantExpr = CTE;
17092     Components.emplace_back(CTE, nullptr, IsNonContiguous);
17093     return true;
17094   }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)17095   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
17096     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
17097     Components.emplace_back(COCE, nullptr, IsNonContiguous);
17098     return true;
17099   }
VisitStmt(Stmt *)17100   bool VisitStmt(Stmt *) {
17101     emitErrorMsg();
17102     return false;
17103   }
getFoundBase() const17104   const Expr *getFoundBase() const {
17105     return RelevantExpr;
17106   }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)17107   explicit MapBaseChecker(
17108       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
17109       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
17110       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
17111       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
17112         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
17113 };
17114 } // namespace
17115 
17116 /// Return the expression of the base of the mappable expression or null if it
17117 /// cannot be determined and do all the necessary checks to see if the expression
17118 /// is valid as a standalone mappable expression. In the process, record all the
17119 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)17120 static const Expr *checkMapClauseExpressionBase(
17121     Sema &SemaRef, Expr *E,
17122     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
17123     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
17124   SourceLocation ELoc = E->getExprLoc();
17125   SourceRange ERange = E->getSourceRange();
17126   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
17127                          ERange);
17128   if (Checker.Visit(E->IgnoreParens())) {
17129     // Check if the highest dimension array section has length specified
17130     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
17131         (CKind == OMPC_to || CKind == OMPC_from)) {
17132       auto CI = CurComponents.rbegin();
17133       auto CE = CurComponents.rend();
17134       for (; CI != CE; ++CI) {
17135         const auto *OASE =
17136             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
17137         if (!OASE)
17138           continue;
17139         if (OASE && OASE->getLength())
17140           break;
17141         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
17142             << ERange;
17143       }
17144     }
17145     return Checker.getFoundBase();
17146   }
17147   return nullptr;
17148 }
17149 
17150 // Return true if expression E associated with value VD has conflicts with other
17151 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)17152 static bool checkMapConflicts(
17153     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
17154     bool CurrentRegionOnly,
17155     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
17156     OpenMPClauseKind CKind) {
17157   assert(VD && E);
17158   SourceLocation ELoc = E->getExprLoc();
17159   SourceRange ERange = E->getSourceRange();
17160 
17161   // In order to easily check the conflicts we need to match each component of
17162   // the expression under test with the components of the expressions that are
17163   // already in the stack.
17164 
17165   assert(!CurComponents.empty() && "Map clause expression with no components!");
17166   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
17167          "Map clause expression with unexpected base!");
17168 
17169   // Variables to help detecting enclosing problems in data environment nests.
17170   bool IsEnclosedByDataEnvironmentExpr = false;
17171   const Expr *EnclosingExpr = nullptr;
17172 
17173   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17174       VD, CurrentRegionOnly,
17175       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17176        ERange, CKind, &EnclosingExpr,
17177        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17178                           StackComponents,
17179                       OpenMPClauseKind) {
17180         assert(!StackComponents.empty() &&
17181                "Map clause expression with no components!");
17182         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
17183                "Map clause expression with unexpected base!");
17184         (void)VD;
17185 
17186         // The whole expression in the stack.
17187         const Expr *RE = StackComponents.front().getAssociatedExpression();
17188 
17189         // Expressions must start from the same base. Here we detect at which
17190         // point both expressions diverge from each other and see if we can
17191         // detect if the memory referred to both expressions is contiguous and
17192         // do not overlap.
17193         auto CI = CurComponents.rbegin();
17194         auto CE = CurComponents.rend();
17195         auto SI = StackComponents.rbegin();
17196         auto SE = StackComponents.rend();
17197         for (; CI != CE && SI != SE; ++CI, ++SI) {
17198 
17199           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17200           //  At most one list item can be an array item derived from a given
17201           //  variable in map clauses of the same construct.
17202           if (CurrentRegionOnly &&
17203               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17204                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17205                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17206               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17207                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17208                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17209             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17210                          diag::err_omp_multiple_array_items_in_map_clause)
17211                 << CI->getAssociatedExpression()->getSourceRange();
17212             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17213                          diag::note_used_here)
17214                 << SI->getAssociatedExpression()->getSourceRange();
17215             return true;
17216           }
17217 
17218           // Do both expressions have the same kind?
17219           if (CI->getAssociatedExpression()->getStmtClass() !=
17220               SI->getAssociatedExpression()->getStmtClass())
17221             break;
17222 
17223           // Are we dealing with different variables/fields?
17224           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17225             break;
17226         }
17227         // Check if the extra components of the expressions in the enclosing
17228         // data environment are redundant for the current base declaration.
17229         // If they are, the maps completely overlap, which is legal.
17230         for (; SI != SE; ++SI) {
17231           QualType Type;
17232           if (const auto *ASE =
17233                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17234             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17235           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17236                          SI->getAssociatedExpression())) {
17237             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17238             Type =
17239                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17240           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17241                          SI->getAssociatedExpression())) {
17242             Type = OASE->getBase()->getType()->getPointeeType();
17243           }
17244           if (Type.isNull() || Type->isAnyPointerType() ||
17245               checkArrayExpressionDoesNotReferToWholeSize(
17246                   SemaRef, SI->getAssociatedExpression(), Type))
17247             break;
17248         }
17249 
17250         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17251         //  List items of map clauses in the same construct must not share
17252         //  original storage.
17253         //
17254         // If the expressions are exactly the same or one is a subset of the
17255         // other, it means they are sharing storage.
17256         if (CI == CE && SI == SE) {
17257           if (CurrentRegionOnly) {
17258             if (CKind == OMPC_map) {
17259               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17260             } else {
17261               assert(CKind == OMPC_to || CKind == OMPC_from);
17262               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17263                   << ERange;
17264             }
17265             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17266                 << RE->getSourceRange();
17267             return true;
17268           }
17269           // If we find the same expression in the enclosing data environment,
17270           // that is legal.
17271           IsEnclosedByDataEnvironmentExpr = true;
17272           return false;
17273         }
17274 
17275         QualType DerivedType =
17276             std::prev(CI)->getAssociatedDeclaration()->getType();
17277         SourceLocation DerivedLoc =
17278             std::prev(CI)->getAssociatedExpression()->getExprLoc();
17279 
17280         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17281         //  If the type of a list item is a reference to a type T then the type
17282         //  will be considered to be T for all purposes of this clause.
17283         DerivedType = DerivedType.getNonReferenceType();
17284 
17285         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17286         //  A variable for which the type is pointer and an array section
17287         //  derived from that variable must not appear as list items of map
17288         //  clauses of the same construct.
17289         //
17290         // Also, cover one of the cases in:
17291         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17292         //  If any part of the original storage of a list item has corresponding
17293         //  storage in the device data environment, all of the original storage
17294         //  must have corresponding storage in the device data environment.
17295         //
17296         if (DerivedType->isAnyPointerType()) {
17297           if (CI == CE || SI == SE) {
17298             SemaRef.Diag(
17299                 DerivedLoc,
17300                 diag::err_omp_pointer_mapped_along_with_derived_section)
17301                 << DerivedLoc;
17302             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17303                 << RE->getSourceRange();
17304             return true;
17305           }
17306           if (CI->getAssociatedExpression()->getStmtClass() !=
17307                          SI->getAssociatedExpression()->getStmtClass() ||
17308                      CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17309                          SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17310             assert(CI != CE && SI != SE);
17311             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17312                 << DerivedLoc;
17313             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17314                 << RE->getSourceRange();
17315             return true;
17316           }
17317         }
17318 
17319         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17320         //  List items of map clauses in the same construct must not share
17321         //  original storage.
17322         //
17323         // An expression is a subset of the other.
17324         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17325           if (CKind == OMPC_map) {
17326             if (CI != CE || SI != SE) {
17327               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17328               // a pointer.
17329               auto Begin =
17330                   CI != CE ? CurComponents.begin() : StackComponents.begin();
17331               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17332               auto It = Begin;
17333               while (It != End && !It->getAssociatedDeclaration())
17334                 std::advance(It, 1);
17335               assert(It != End &&
17336                      "Expected at least one component with the declaration.");
17337               if (It != Begin && It->getAssociatedDeclaration()
17338                                      ->getType()
17339                                      .getCanonicalType()
17340                                      ->isAnyPointerType()) {
17341                 IsEnclosedByDataEnvironmentExpr = false;
17342                 EnclosingExpr = nullptr;
17343                 return false;
17344               }
17345             }
17346             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17347           } else {
17348             assert(CKind == OMPC_to || CKind == OMPC_from);
17349             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17350                 << ERange;
17351           }
17352           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17353               << RE->getSourceRange();
17354           return true;
17355         }
17356 
17357         // The current expression uses the same base as other expression in the
17358         // data environment but does not contain it completely.
17359         if (!CurrentRegionOnly && SI != SE)
17360           EnclosingExpr = RE;
17361 
17362         // The current expression is a subset of the expression in the data
17363         // environment.
17364         IsEnclosedByDataEnvironmentExpr |=
17365             (!CurrentRegionOnly && CI != CE && SI == SE);
17366 
17367         return false;
17368       });
17369 
17370   if (CurrentRegionOnly)
17371     return FoundError;
17372 
17373   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17374   //  If any part of the original storage of a list item has corresponding
17375   //  storage in the device data environment, all of the original storage must
17376   //  have corresponding storage in the device data environment.
17377   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17378   //  If a list item is an element of a structure, and a different element of
17379   //  the structure has a corresponding list item in the device data environment
17380   //  prior to a task encountering the construct associated with the map clause,
17381   //  then the list item must also have a corresponding list item in the device
17382   //  data environment prior to the task encountering the construct.
17383   //
17384   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17385     SemaRef.Diag(ELoc,
17386                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
17387         << ERange;
17388     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17389         << EnclosingExpr->getSourceRange();
17390     return true;
17391   }
17392 
17393   return FoundError;
17394 }
17395 
17396 // Look up the user-defined mapper given the mapper name and mapped type, and
17397 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)17398 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17399                                             CXXScopeSpec &MapperIdScopeSpec,
17400                                             const DeclarationNameInfo &MapperId,
17401                                             QualType Type,
17402                                             Expr *UnresolvedMapper) {
17403   if (MapperIdScopeSpec.isInvalid())
17404     return ExprError();
17405   // Get the actual type for the array type.
17406   if (Type->isArrayType()) {
17407     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
17408     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17409   }
17410   // Find all user-defined mappers with the given MapperId.
17411   SmallVector<UnresolvedSet<8>, 4> Lookups;
17412   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17413   Lookup.suppressDiagnostics();
17414   if (S) {
17415     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17416       NamedDecl *D = Lookup.getRepresentativeDecl();
17417       while (S && !S->isDeclScope(D))
17418         S = S->getParent();
17419       if (S)
17420         S = S->getParent();
17421       Lookups.emplace_back();
17422       Lookups.back().append(Lookup.begin(), Lookup.end());
17423       Lookup.clear();
17424     }
17425   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17426     // Extract the user-defined mappers with the given MapperId.
17427     Lookups.push_back(UnresolvedSet<8>());
17428     for (NamedDecl *D : ULE->decls()) {
17429       auto *DMD = cast<OMPDeclareMapperDecl>(D);
17430       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
17431       Lookups.back().addDecl(DMD);
17432     }
17433   }
17434   // Defer the lookup for dependent types. The results will be passed through
17435   // UnresolvedMapper on instantiation.
17436   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17437       Type->isInstantiationDependentType() ||
17438       Type->containsUnexpandedParameterPack() ||
17439       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17440         return !D->isInvalidDecl() &&
17441                (D->getType()->isDependentType() ||
17442                 D->getType()->isInstantiationDependentType() ||
17443                 D->getType()->containsUnexpandedParameterPack());
17444       })) {
17445     UnresolvedSet<8> URS;
17446     for (const UnresolvedSet<8> &Set : Lookups) {
17447       if (Set.empty())
17448         continue;
17449       URS.append(Set.begin(), Set.end());
17450     }
17451     return UnresolvedLookupExpr::Create(
17452         SemaRef.Context, /*NamingClass=*/nullptr,
17453         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17454         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17455   }
17456   SourceLocation Loc = MapperId.getLoc();
17457   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17458   //  The type must be of struct, union or class type in C and C++
17459   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17460       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17461     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17462     return ExprError();
17463   }
17464   // Perform argument dependent lookup.
17465   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17466     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17467   // Return the first user-defined mapper with the desired type.
17468   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17469           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17470             if (!D->isInvalidDecl() &&
17471                 SemaRef.Context.hasSameType(D->getType(), Type))
17472               return D;
17473             return nullptr;
17474           }))
17475     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17476   // Find the first user-defined mapper with a type derived from the desired
17477   // type.
17478   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17479           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17480             if (!D->isInvalidDecl() &&
17481                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17482                 !Type.isMoreQualifiedThan(D->getType()))
17483               return D;
17484             return nullptr;
17485           })) {
17486     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17487                        /*DetectVirtual=*/false);
17488     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17489       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17490               VD->getType().getUnqualifiedType()))) {
17491         if (SemaRef.CheckBaseClassAccess(
17492                 Loc, VD->getType(), Type, Paths.front(),
17493                 /*DiagID=*/0) != Sema::AR_inaccessible) {
17494           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17495         }
17496       }
17497     }
17498   }
17499   // Report error if a mapper is specified, but cannot be found.
17500   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17501     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17502         << Type << MapperId.getName();
17503     return ExprError();
17504   }
17505   return ExprEmpty();
17506 }
17507 
17508 namespace {
17509 // Utility struct that gathers all the related lists associated with a mappable
17510 // expression.
17511 struct MappableVarListInfo {
17512   // The list of expressions.
17513   ArrayRef<Expr *> VarList;
17514   // The list of processed expressions.
17515   SmallVector<Expr *, 16> ProcessedVarList;
17516   // The mappble components for each expression.
17517   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17518   // The base declaration of the variable.
17519   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17520   // The reference to the user-defined mapper associated with every expression.
17521   SmallVector<Expr *, 16> UDMapperList;
17522 
MappableVarListInfo__anon0bb9e2bb4e11::MappableVarListInfo17523   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17524     // We have a list of components and base declarations for each entry in the
17525     // variable list.
17526     VarComponents.reserve(VarList.size());
17527     VarBaseDeclarations.reserve(VarList.size());
17528   }
17529 };
17530 }
17531 
17532 // Check the validity of the provided variable list for the provided clause kind
17533 // \a CKind. In the check process the valid expressions, mappable expression
17534 // components, variables, and user-defined mappers are extracted and used to
17535 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17536 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17537 // and \a MapperId are expected to be valid if the clause kind is 'map'.
checkMappableExpressionList(Sema & SemaRef,DSAStackTy * DSAS,OpenMPClauseKind CKind,MappableVarListInfo & MVLI,SourceLocation StartLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo MapperId,ArrayRef<Expr * > UnresolvedMappers,OpenMPMapClauseKind MapType=OMPC_MAP_unknown,bool IsMapTypeImplicit=false)17538 static void checkMappableExpressionList(
17539     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17540     MappableVarListInfo &MVLI, SourceLocation StartLoc,
17541     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17542     ArrayRef<Expr *> UnresolvedMappers,
17543     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17544     bool IsMapTypeImplicit = false) {
17545   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17546   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
17547          "Unexpected clause kind with mappable expressions!");
17548 
17549   // If the identifier of user-defined mapper is not specified, it is "default".
17550   // We do not change the actual name in this clause to distinguish whether a
17551   // mapper is specified explicitly, i.e., it is not explicitly specified when
17552   // MapperId.getName() is empty.
17553   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17554     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17555     MapperId.setName(DeclNames.getIdentifier(
17556         &SemaRef.getASTContext().Idents.get("default")));
17557     MapperId.setLoc(StartLoc);
17558   }
17559 
17560   // Iterators to find the current unresolved mapper expression.
17561   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17562   bool UpdateUMIt = false;
17563   Expr *UnresolvedMapper = nullptr;
17564 
17565   // Keep track of the mappable components and base declarations in this clause.
17566   // Each entry in the list is going to have a list of components associated. We
17567   // record each set of the components so that we can build the clause later on.
17568   // In the end we should have the same amount of declarations and component
17569   // lists.
17570 
17571   for (Expr *RE : MVLI.VarList) {
17572     assert(RE && "Null expr in omp to/from/map clause");
17573     SourceLocation ELoc = RE->getExprLoc();
17574 
17575     // Find the current unresolved mapper expression.
17576     if (UpdateUMIt && UMIt != UMEnd) {
17577       UMIt++;
17578       assert(
17579           UMIt != UMEnd &&
17580           "Expect the size of UnresolvedMappers to match with that of VarList");
17581     }
17582     UpdateUMIt = true;
17583     if (UMIt != UMEnd)
17584       UnresolvedMapper = *UMIt;
17585 
17586     const Expr *VE = RE->IgnoreParenLValueCasts();
17587 
17588     if (VE->isValueDependent() || VE->isTypeDependent() ||
17589         VE->isInstantiationDependent() ||
17590         VE->containsUnexpandedParameterPack()) {
17591       // Try to find the associated user-defined mapper.
17592       ExprResult ER = buildUserDefinedMapperRef(
17593           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17594           VE->getType().getCanonicalType(), UnresolvedMapper);
17595       if (ER.isInvalid())
17596         continue;
17597       MVLI.UDMapperList.push_back(ER.get());
17598       // We can only analyze this information once the missing information is
17599       // resolved.
17600       MVLI.ProcessedVarList.push_back(RE);
17601       continue;
17602     }
17603 
17604     Expr *SimpleExpr = RE->IgnoreParenCasts();
17605 
17606     if (!RE->isLValue()) {
17607       if (SemaRef.getLangOpts().OpenMP < 50) {
17608         SemaRef.Diag(
17609             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17610             << RE->getSourceRange();
17611       } else {
17612         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17613             << getOpenMPClauseName(CKind) << RE->getSourceRange();
17614       }
17615       continue;
17616     }
17617 
17618     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17619     ValueDecl *CurDeclaration = nullptr;
17620 
17621     // Obtain the array or member expression bases if required. Also, fill the
17622     // components array with all the components identified in the process.
17623     const Expr *BE = checkMapClauseExpressionBase(
17624         SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
17625         /*NoDiagnose=*/false);
17626     if (!BE)
17627       continue;
17628 
17629     assert(!CurComponents.empty() &&
17630            "Invalid mappable expression information.");
17631 
17632     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17633       // Add store "this" pointer to class in DSAStackTy for future checking
17634       DSAS->addMappedClassesQualTypes(TE->getType());
17635       // Try to find the associated user-defined mapper.
17636       ExprResult ER = buildUserDefinedMapperRef(
17637           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17638           VE->getType().getCanonicalType(), UnresolvedMapper);
17639       if (ER.isInvalid())
17640         continue;
17641       MVLI.UDMapperList.push_back(ER.get());
17642       // Skip restriction checking for variable or field declarations
17643       MVLI.ProcessedVarList.push_back(RE);
17644       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17645       MVLI.VarComponents.back().append(CurComponents.begin(),
17646                                        CurComponents.end());
17647       MVLI.VarBaseDeclarations.push_back(nullptr);
17648       continue;
17649     }
17650 
17651     // For the following checks, we rely on the base declaration which is
17652     // expected to be associated with the last component. The declaration is
17653     // expected to be a variable or a field (if 'this' is being mapped).
17654     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17655     assert(CurDeclaration && "Null decl on map clause.");
17656     assert(
17657         CurDeclaration->isCanonicalDecl() &&
17658         "Expecting components to have associated only canonical declarations.");
17659 
17660     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17661     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17662 
17663     assert((VD || FD) && "Only variables or fields are expected here!");
17664     (void)FD;
17665 
17666     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17667     // threadprivate variables cannot appear in a map clause.
17668     // OpenMP 4.5 [2.10.5, target update Construct]
17669     // threadprivate variables cannot appear in a from clause.
17670     if (VD && DSAS->isThreadPrivate(VD)) {
17671       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17672       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17673           << getOpenMPClauseName(CKind);
17674       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17675       continue;
17676     }
17677 
17678     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17679     //  A list item cannot appear in both a map clause and a data-sharing
17680     //  attribute clause on the same construct.
17681 
17682     // Check conflicts with other map clause expressions. We check the conflicts
17683     // with the current construct separately from the enclosing data
17684     // environment, because the restrictions are different. We only have to
17685     // check conflicts across regions for the map clauses.
17686     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17687                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
17688       break;
17689     if (CKind == OMPC_map &&
17690         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17691         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17692                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
17693       break;
17694 
17695     // OpenMP 4.5 [2.10.5, target update Construct]
17696     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17697     //  If the type of a list item is a reference to a type T then the type will
17698     //  be considered to be T for all purposes of this clause.
17699     auto I = llvm::find_if(
17700         CurComponents,
17701         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17702           return MC.getAssociatedDeclaration();
17703         });
17704     assert(I != CurComponents.end() && "Null decl on map clause.");
17705     QualType Type;
17706     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17707     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17708     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17709     if (ASE) {
17710       Type = ASE->getType().getNonReferenceType();
17711     } else if (OASE) {
17712       QualType BaseType =
17713           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17714       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17715         Type = ATy->getElementType();
17716       else
17717         Type = BaseType->getPointeeType();
17718       Type = Type.getNonReferenceType();
17719     } else if (OAShE) {
17720       Type = OAShE->getBase()->getType()->getPointeeType();
17721     } else {
17722       Type = VE->getType();
17723     }
17724 
17725     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17726     // A list item in a to or from clause must have a mappable type.
17727     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17728     //  A list item must have a mappable type.
17729     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17730                            DSAS, Type))
17731       continue;
17732 
17733     Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17734 
17735     if (CKind == OMPC_map) {
17736       // target enter data
17737       // OpenMP [2.10.2, Restrictions, p. 99]
17738       // A map-type must be specified in all map clauses and must be either
17739       // to or alloc.
17740       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17741       if (DKind == OMPD_target_enter_data &&
17742           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17743         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17744             << (IsMapTypeImplicit ? 1 : 0)
17745             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17746             << getOpenMPDirectiveName(DKind);
17747         continue;
17748       }
17749 
17750       // target exit_data
17751       // OpenMP [2.10.3, Restrictions, p. 102]
17752       // A map-type must be specified in all map clauses and must be either
17753       // from, release, or delete.
17754       if (DKind == OMPD_target_exit_data &&
17755           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17756             MapType == OMPC_MAP_delete)) {
17757         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17758             << (IsMapTypeImplicit ? 1 : 0)
17759             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17760             << getOpenMPDirectiveName(DKind);
17761         continue;
17762       }
17763 
17764       // target, target data
17765       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17766       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17767       // A map-type in a map clause must be to, from, tofrom or alloc
17768       if ((DKind == OMPD_target_data ||
17769            isOpenMPTargetExecutionDirective(DKind)) &&
17770           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17771             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17772         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17773             << (IsMapTypeImplicit ? 1 : 0)
17774             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17775             << getOpenMPDirectiveName(DKind);
17776         continue;
17777       }
17778 
17779       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17780       // A list item cannot appear in both a map clause and a data-sharing
17781       // attribute clause on the same construct
17782       //
17783       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17784       // A list item cannot appear in both a map clause and a data-sharing
17785       // attribute clause on the same construct unless the construct is a
17786       // combined construct.
17787       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17788                   isOpenMPTargetExecutionDirective(DKind)) ||
17789                  DKind == OMPD_target)) {
17790         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17791         if (isOpenMPPrivate(DVar.CKind)) {
17792           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17793               << getOpenMPClauseName(DVar.CKind)
17794               << getOpenMPClauseName(OMPC_map)
17795               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17796           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17797           continue;
17798         }
17799       }
17800     }
17801 
17802     // Try to find the associated user-defined mapper.
17803     ExprResult ER = buildUserDefinedMapperRef(
17804         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17805         Type.getCanonicalType(), UnresolvedMapper);
17806     if (ER.isInvalid())
17807       continue;
17808     MVLI.UDMapperList.push_back(ER.get());
17809 
17810     // Save the current expression.
17811     MVLI.ProcessedVarList.push_back(RE);
17812 
17813     // Store the components in the stack so that they can be used to check
17814     // against other clauses later on.
17815     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17816                                           /*WhereFoundClauseKind=*/OMPC_map);
17817 
17818     // Save the components and declaration to create the clause. For purposes of
17819     // the clause creation, any component list that has has base 'this' uses
17820     // null as base declaration.
17821     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17822     MVLI.VarComponents.back().append(CurComponents.begin(),
17823                                      CurComponents.end());
17824     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17825                                                            : CurDeclaration);
17826   }
17827 }
17828 
ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)17829 OMPClause *Sema::ActOnOpenMPMapClause(
17830     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17831     ArrayRef<SourceLocation> MapTypeModifiersLoc,
17832     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17833     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17834     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17835     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17836   OpenMPMapModifierKind Modifiers[] = {
17837       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17838       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17839   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17840 
17841   // Process map-type-modifiers, flag errors for duplicate modifiers.
17842   unsigned Count = 0;
17843   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17844     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17845         llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17846       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17847       continue;
17848     }
17849     assert(Count < NumberOfOMPMapClauseModifiers &&
17850            "Modifiers exceed the allowed number of map type modifiers");
17851     Modifiers[Count] = MapTypeModifiers[I];
17852     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17853     ++Count;
17854   }
17855 
17856   MappableVarListInfo MVLI(VarList);
17857   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
17858                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
17859                               MapType, IsMapTypeImplicit);
17860 
17861   // We need to produce a map clause even if we don't have variables so that
17862   // other diagnostics related with non-existing map clauses are accurate.
17863   return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
17864                               MVLI.VarBaseDeclarations, MVLI.VarComponents,
17865                               MVLI.UDMapperList, Modifiers, ModifiersLoc,
17866                               MapperIdScopeSpec.getWithLocInContext(Context),
17867                               MapperId, MapType, IsMapTypeImplicit, MapLoc);
17868 }
17869 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)17870 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
17871                                                TypeResult ParsedType) {
17872   assert(ParsedType.isUsable());
17873 
17874   QualType ReductionType = GetTypeFromParser(ParsedType.get());
17875   if (ReductionType.isNull())
17876     return QualType();
17877 
17878   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
17879   // A type name in a declare reduction directive cannot be a function type, an
17880   // array type, a reference type, or a type qualified with const, volatile or
17881   // restrict.
17882   if (ReductionType.hasQualifiers()) {
17883     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
17884     return QualType();
17885   }
17886 
17887   if (ReductionType->isFunctionType()) {
17888     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
17889     return QualType();
17890   }
17891   if (ReductionType->isReferenceType()) {
17892     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
17893     return QualType();
17894   }
17895   if (ReductionType->isArrayType()) {
17896     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
17897     return QualType();
17898   }
17899   return ReductionType;
17900 }
17901 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)17902 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
17903     Scope *S, DeclContext *DC, DeclarationName Name,
17904     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
17905     AccessSpecifier AS, Decl *PrevDeclInScope) {
17906   SmallVector<Decl *, 8> Decls;
17907   Decls.reserve(ReductionTypes.size());
17908 
17909   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
17910                       forRedeclarationInCurContext());
17911   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
17912   // A reduction-identifier may not be re-declared in the current scope for the
17913   // same type or for a type that is compatible according to the base language
17914   // rules.
17915   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17916   OMPDeclareReductionDecl *PrevDRD = nullptr;
17917   bool InCompoundScope = true;
17918   if (S != nullptr) {
17919     // Find previous declaration with the same name not referenced in other
17920     // declarations.
17921     FunctionScopeInfo *ParentFn = getEnclosingFunction();
17922     InCompoundScope =
17923         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17924     LookupName(Lookup, S);
17925     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17926                          /*AllowInlineNamespace=*/false);
17927     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
17928     LookupResult::Filter Filter = Lookup.makeFilter();
17929     while (Filter.hasNext()) {
17930       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
17931       if (InCompoundScope) {
17932         auto I = UsedAsPrevious.find(PrevDecl);
17933         if (I == UsedAsPrevious.end())
17934           UsedAsPrevious[PrevDecl] = false;
17935         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
17936           UsedAsPrevious[D] = true;
17937       }
17938       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17939           PrevDecl->getLocation();
17940     }
17941     Filter.done();
17942     if (InCompoundScope) {
17943       for (const auto &PrevData : UsedAsPrevious) {
17944         if (!PrevData.second) {
17945           PrevDRD = PrevData.first;
17946           break;
17947         }
17948       }
17949     }
17950   } else if (PrevDeclInScope != nullptr) {
17951     auto *PrevDRDInScope = PrevDRD =
17952         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
17953     do {
17954       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
17955           PrevDRDInScope->getLocation();
17956       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
17957     } while (PrevDRDInScope != nullptr);
17958   }
17959   for (const auto &TyData : ReductionTypes) {
17960     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
17961     bool Invalid = false;
17962     if (I != PreviousRedeclTypes.end()) {
17963       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
17964           << TyData.first;
17965       Diag(I->second, diag::note_previous_definition);
17966       Invalid = true;
17967     }
17968     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
17969     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
17970                                                 Name, TyData.first, PrevDRD);
17971     DC->addDecl(DRD);
17972     DRD->setAccess(AS);
17973     Decls.push_back(DRD);
17974     if (Invalid)
17975       DRD->setInvalidDecl();
17976     else
17977       PrevDRD = DRD;
17978   }
17979 
17980   return DeclGroupPtrTy::make(
17981       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
17982 }
17983 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)17984 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
17985   auto *DRD = cast<OMPDeclareReductionDecl>(D);
17986 
17987   // Enter new function scope.
17988   PushFunctionScope();
17989   setFunctionHasBranchProtectedScope();
17990   getCurFunction()->setHasOMPDeclareReductionCombiner();
17991 
17992   if (S != nullptr)
17993     PushDeclContext(S, DRD);
17994   else
17995     CurContext = DRD;
17996 
17997   PushExpressionEvaluationContext(
17998       ExpressionEvaluationContext::PotentiallyEvaluated);
17999 
18000   QualType ReductionType = DRD->getType();
18001   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
18002   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
18003   // uses semantics of argument handles by value, but it should be passed by
18004   // reference. C lang does not support references, so pass all parameters as
18005   // pointers.
18006   // Create 'T omp_in;' variable.
18007   VarDecl *OmpInParm =
18008       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
18009   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
18010   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
18011   // uses semantics of argument handles by value, but it should be passed by
18012   // reference. C lang does not support references, so pass all parameters as
18013   // pointers.
18014   // Create 'T omp_out;' variable.
18015   VarDecl *OmpOutParm =
18016       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
18017   if (S != nullptr) {
18018     PushOnScopeChains(OmpInParm, S);
18019     PushOnScopeChains(OmpOutParm, S);
18020   } else {
18021     DRD->addDecl(OmpInParm);
18022     DRD->addDecl(OmpOutParm);
18023   }
18024   Expr *InE =
18025       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
18026   Expr *OutE =
18027       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
18028   DRD->setCombinerData(InE, OutE);
18029 }
18030 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)18031 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
18032   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18033   DiscardCleanupsInEvaluationContext();
18034   PopExpressionEvaluationContext();
18035 
18036   PopDeclContext();
18037   PopFunctionScopeInfo();
18038 
18039   if (Combiner != nullptr)
18040     DRD->setCombiner(Combiner);
18041   else
18042     DRD->setInvalidDecl();
18043 }
18044 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)18045 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
18046   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18047 
18048   // Enter new function scope.
18049   PushFunctionScope();
18050   setFunctionHasBranchProtectedScope();
18051 
18052   if (S != nullptr)
18053     PushDeclContext(S, DRD);
18054   else
18055     CurContext = DRD;
18056 
18057   PushExpressionEvaluationContext(
18058       ExpressionEvaluationContext::PotentiallyEvaluated);
18059 
18060   QualType ReductionType = DRD->getType();
18061   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
18062   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
18063   // uses semantics of argument handles by value, but it should be passed by
18064   // reference. C lang does not support references, so pass all parameters as
18065   // pointers.
18066   // Create 'T omp_priv;' variable.
18067   VarDecl *OmpPrivParm =
18068       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
18069   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
18070   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
18071   // uses semantics of argument handles by value, but it should be passed by
18072   // reference. C lang does not support references, so pass all parameters as
18073   // pointers.
18074   // Create 'T omp_orig;' variable.
18075   VarDecl *OmpOrigParm =
18076       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
18077   if (S != nullptr) {
18078     PushOnScopeChains(OmpPrivParm, S);
18079     PushOnScopeChains(OmpOrigParm, S);
18080   } else {
18081     DRD->addDecl(OmpPrivParm);
18082     DRD->addDecl(OmpOrigParm);
18083   }
18084   Expr *OrigE =
18085       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
18086   Expr *PrivE =
18087       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
18088   DRD->setInitializerData(OrigE, PrivE);
18089   return OmpPrivParm;
18090 }
18091 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)18092 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
18093                                                      VarDecl *OmpPrivParm) {
18094   auto *DRD = cast<OMPDeclareReductionDecl>(D);
18095   DiscardCleanupsInEvaluationContext();
18096   PopExpressionEvaluationContext();
18097 
18098   PopDeclContext();
18099   PopFunctionScopeInfo();
18100 
18101   if (Initializer != nullptr) {
18102     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
18103   } else if (OmpPrivParm->hasInit()) {
18104     DRD->setInitializer(OmpPrivParm->getInit(),
18105                         OmpPrivParm->isDirectInit()
18106                             ? OMPDeclareReductionDecl::DirectInit
18107                             : OMPDeclareReductionDecl::CopyInit);
18108   } else {
18109     DRD->setInvalidDecl();
18110   }
18111 }
18112 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)18113 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
18114     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
18115   for (Decl *D : DeclReductions.get()) {
18116     if (IsValid) {
18117       if (S)
18118         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
18119                           /*AddToContext=*/false);
18120     } else {
18121       D->setInvalidDecl();
18122     }
18123   }
18124   return DeclReductions;
18125 }
18126 
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)18127 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
18128   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
18129   QualType T = TInfo->getType();
18130   if (D.isInvalidType())
18131     return true;
18132 
18133   if (getLangOpts().CPlusPlus) {
18134     // Check that there are no default arguments (C++ only).
18135     CheckExtraCXXDefaultArguments(D);
18136   }
18137 
18138   return CreateParsedType(T, TInfo);
18139 }
18140 
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)18141 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
18142                                             TypeResult ParsedType) {
18143   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
18144 
18145   QualType MapperType = GetTypeFromParser(ParsedType.get());
18146   assert(!MapperType.isNull() && "Expect valid mapper type");
18147 
18148   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18149   //  The type must be of struct, union or class type in C and C++
18150   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
18151     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
18152     return QualType();
18153   }
18154   return MapperType;
18155 }
18156 
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)18157 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
18158     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
18159     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
18160     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
18161   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
18162                       forRedeclarationInCurContext());
18163   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18164   //  A mapper-identifier may not be redeclared in the current scope for the
18165   //  same type or for a type that is compatible according to the base language
18166   //  rules.
18167   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
18168   OMPDeclareMapperDecl *PrevDMD = nullptr;
18169   bool InCompoundScope = true;
18170   if (S != nullptr) {
18171     // Find previous declaration with the same name not referenced in other
18172     // declarations.
18173     FunctionScopeInfo *ParentFn = getEnclosingFunction();
18174     InCompoundScope =
18175         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18176     LookupName(Lookup, S);
18177     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18178                          /*AllowInlineNamespace=*/false);
18179     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18180     LookupResult::Filter Filter = Lookup.makeFilter();
18181     while (Filter.hasNext()) {
18182       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18183       if (InCompoundScope) {
18184         auto I = UsedAsPrevious.find(PrevDecl);
18185         if (I == UsedAsPrevious.end())
18186           UsedAsPrevious[PrevDecl] = false;
18187         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18188           UsedAsPrevious[D] = true;
18189       }
18190       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18191           PrevDecl->getLocation();
18192     }
18193     Filter.done();
18194     if (InCompoundScope) {
18195       for (const auto &PrevData : UsedAsPrevious) {
18196         if (!PrevData.second) {
18197           PrevDMD = PrevData.first;
18198           break;
18199         }
18200       }
18201     }
18202   } else if (PrevDeclInScope) {
18203     auto *PrevDMDInScope = PrevDMD =
18204         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18205     do {
18206       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18207           PrevDMDInScope->getLocation();
18208       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18209     } while (PrevDMDInScope != nullptr);
18210   }
18211   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18212   bool Invalid = false;
18213   if (I != PreviousRedeclTypes.end()) {
18214     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18215         << MapperType << Name;
18216     Diag(I->second, diag::note_previous_definition);
18217     Invalid = true;
18218   }
18219   auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18220                                            MapperType, VN, Clauses, PrevDMD);
18221   if (S)
18222     PushOnScopeChains(DMD, S);
18223   else
18224     DC->addDecl(DMD);
18225   DMD->setAccess(AS);
18226   if (Invalid)
18227     DMD->setInvalidDecl();
18228 
18229   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
18230   VD->setDeclContext(DMD);
18231   VD->setLexicalDeclContext(DMD);
18232   DMD->addDecl(VD);
18233   DMD->setMapperVarRef(MapperVarRef);
18234 
18235   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
18236 }
18237 
18238 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)18239 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
18240                                                SourceLocation StartLoc,
18241                                                DeclarationName VN) {
18242   TypeSourceInfo *TInfo =
18243       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
18244   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
18245                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
18246                              MapperType, TInfo, SC_None);
18247   if (S)
18248     PushOnScopeChains(VD, S, /*AddToContext=*/false);
18249   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18250   DSAStack->addDeclareMapperVarRef(E);
18251   return E;
18252 }
18253 
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const18254 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
18255   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18256   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
18257   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
18258     return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
18259   return true;
18260 }
18261 
getOpenMPDeclareMapperVarName() const18262 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
18263   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
18264   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
18265 }
18266 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18267 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18268                                            SourceLocation StartLoc,
18269                                            SourceLocation LParenLoc,
18270                                            SourceLocation EndLoc) {
18271   Expr *ValExpr = NumTeams;
18272   Stmt *HelperValStmt = nullptr;
18273 
18274   // OpenMP [teams Constrcut, Restrictions]
18275   // The num_teams expression must evaluate to a positive integer value.
18276   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18277                                  /*StrictlyPositive=*/true))
18278     return nullptr;
18279 
18280   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18281   OpenMPDirectiveKind CaptureRegion =
18282       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18283   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18284     ValExpr = MakeFullExpr(ValExpr).get();
18285     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18286     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18287     HelperValStmt = buildPreInits(Context, Captures);
18288   }
18289 
18290   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18291                                          StartLoc, LParenLoc, EndLoc);
18292 }
18293 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18294 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18295                                               SourceLocation StartLoc,
18296                                               SourceLocation LParenLoc,
18297                                               SourceLocation EndLoc) {
18298   Expr *ValExpr = ThreadLimit;
18299   Stmt *HelperValStmt = nullptr;
18300 
18301   // OpenMP [teams Constrcut, Restrictions]
18302   // The thread_limit expression must evaluate to a positive integer value.
18303   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18304                                  /*StrictlyPositive=*/true))
18305     return nullptr;
18306 
18307   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18308   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18309       DKind, OMPC_thread_limit, LangOpts.OpenMP);
18310   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18311     ValExpr = MakeFullExpr(ValExpr).get();
18312     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18313     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18314     HelperValStmt = buildPreInits(Context, Captures);
18315   }
18316 
18317   return new (Context) OMPThreadLimitClause(
18318       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18319 }
18320 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18321 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18322                                            SourceLocation StartLoc,
18323                                            SourceLocation LParenLoc,
18324                                            SourceLocation EndLoc) {
18325   Expr *ValExpr = Priority;
18326   Stmt *HelperValStmt = nullptr;
18327   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18328 
18329   // OpenMP [2.9.1, task Constrcut]
18330   // The priority-value is a non-negative numerical scalar expression.
18331   if (!isNonNegativeIntegerValue(
18332           ValExpr, *this, OMPC_priority,
18333           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18334           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18335     return nullptr;
18336 
18337   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18338                                          StartLoc, LParenLoc, EndLoc);
18339 }
18340 
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18341 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18342                                             SourceLocation StartLoc,
18343                                             SourceLocation LParenLoc,
18344                                             SourceLocation EndLoc) {
18345   Expr *ValExpr = Grainsize;
18346   Stmt *HelperValStmt = nullptr;
18347   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18348 
18349   // OpenMP [2.9.2, taskloop Constrcut]
18350   // The parameter of the grainsize clause must be a positive integer
18351   // expression.
18352   if (!isNonNegativeIntegerValue(
18353           ValExpr, *this, OMPC_grainsize,
18354           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18355           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18356     return nullptr;
18357 
18358   return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18359                                           StartLoc, LParenLoc, EndLoc);
18360 }
18361 
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18362 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18363                                            SourceLocation StartLoc,
18364                                            SourceLocation LParenLoc,
18365                                            SourceLocation EndLoc) {
18366   Expr *ValExpr = NumTasks;
18367   Stmt *HelperValStmt = nullptr;
18368   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18369 
18370   // OpenMP [2.9.2, taskloop Constrcut]
18371   // The parameter of the num_tasks clause must be a positive integer
18372   // expression.
18373   if (!isNonNegativeIntegerValue(
18374           ValExpr, *this, OMPC_num_tasks,
18375           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18376           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18377     return nullptr;
18378 
18379   return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18380                                          StartLoc, LParenLoc, EndLoc);
18381 }
18382 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18383 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18384                                        SourceLocation LParenLoc,
18385                                        SourceLocation EndLoc) {
18386   // OpenMP [2.13.2, critical construct, Description]
18387   // ... where hint-expression is an integer constant expression that evaluates
18388   // to a valid lock hint.
18389   ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18390   if (HintExpr.isInvalid())
18391     return nullptr;
18392   return new (Context)
18393       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18394 }
18395 
18396 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)18397 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18398                                 DSAStackTy *Stack) {
18399   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18400   if (!OMPEventHandleT.isNull())
18401     return true;
18402   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18403   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18404   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18405     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18406     return false;
18407   }
18408   Stack->setOMPEventHandleT(PT.get());
18409   return true;
18410 }
18411 
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18412 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18413                                          SourceLocation LParenLoc,
18414                                          SourceLocation EndLoc) {
18415   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18416       !Evt->isInstantiationDependent() &&
18417       !Evt->containsUnexpandedParameterPack()) {
18418     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
18419       return nullptr;
18420     // OpenMP 5.0, 2.10.1 task Construct.
18421     // event-handle is a variable of the omp_event_handle_t type.
18422     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18423     if (!Ref) {
18424       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18425           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18426       return nullptr;
18427     }
18428     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18429     if (!VD) {
18430       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18431           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18432       return nullptr;
18433     }
18434     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
18435                                         VD->getType()) ||
18436         VD->getType().isConstant(Context)) {
18437       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18438           << "omp_event_handle_t" << 1 << VD->getType()
18439           << Evt->getSourceRange();
18440       return nullptr;
18441     }
18442     // OpenMP 5.0, 2.10.1 task Construct
18443     // [detach clause]... The event-handle will be considered as if it was
18444     // specified on a firstprivate clause.
18445     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
18446     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18447         DVar.RefExpr) {
18448       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18449           << getOpenMPClauseName(DVar.CKind)
18450           << getOpenMPClauseName(OMPC_firstprivate);
18451       reportOriginalDsa(*this, DSAStack, VD, DVar);
18452       return nullptr;
18453     }
18454   }
18455 
18456   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18457 }
18458 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)18459 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18460     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18461     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18462     SourceLocation EndLoc) {
18463   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18464     std::string Values;
18465     Values += "'";
18466     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18467     Values += "'";
18468     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18469         << Values << getOpenMPClauseName(OMPC_dist_schedule);
18470     return nullptr;
18471   }
18472   Expr *ValExpr = ChunkSize;
18473   Stmt *HelperValStmt = nullptr;
18474   if (ChunkSize) {
18475     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18476         !ChunkSize->isInstantiationDependent() &&
18477         !ChunkSize->containsUnexpandedParameterPack()) {
18478       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18479       ExprResult Val =
18480           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18481       if (Val.isInvalid())
18482         return nullptr;
18483 
18484       ValExpr = Val.get();
18485 
18486       // OpenMP [2.7.1, Restrictions]
18487       //  chunk_size must be a loop invariant integer expression with a positive
18488       //  value.
18489       if (Optional<llvm::APSInt> Result =
18490               ValExpr->getIntegerConstantExpr(Context)) {
18491         if (Result->isSigned() && !Result->isStrictlyPositive()) {
18492           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18493               << "dist_schedule" << ChunkSize->getSourceRange();
18494           return nullptr;
18495         }
18496       } else if (getOpenMPCaptureRegionForClause(
18497                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
18498                      LangOpts.OpenMP) != OMPD_unknown &&
18499                  !CurContext->isDependentContext()) {
18500         ValExpr = MakeFullExpr(ValExpr).get();
18501         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18502         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18503         HelperValStmt = buildPreInits(Context, Captures);
18504       }
18505     }
18506   }
18507 
18508   return new (Context)
18509       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18510                             Kind, ValExpr, HelperValStmt);
18511 }
18512 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)18513 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18514     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18515     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18516     SourceLocation KindLoc, SourceLocation EndLoc) {
18517   if (getLangOpts().OpenMP < 50) {
18518     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18519         Kind != OMPC_DEFAULTMAP_scalar) {
18520       std::string Value;
18521       SourceLocation Loc;
18522       Value += "'";
18523       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18524         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18525                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
18526         Loc = MLoc;
18527       } else {
18528         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18529                                                OMPC_DEFAULTMAP_scalar);
18530         Loc = KindLoc;
18531       }
18532       Value += "'";
18533       Diag(Loc, diag::err_omp_unexpected_clause_value)
18534           << Value << getOpenMPClauseName(OMPC_defaultmap);
18535       return nullptr;
18536     }
18537   } else {
18538     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18539     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18540                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18541     if (!isDefaultmapKind || !isDefaultmapModifier) {
18542       std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18543                                   "'firstprivate', 'none', 'default'";
18544       std::string KindValue = "'scalar', 'aggregate', 'pointer'";
18545       if (!isDefaultmapKind && isDefaultmapModifier) {
18546         Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18547             << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18548       } else if (isDefaultmapKind && !isDefaultmapModifier) {
18549         Diag(MLoc, diag::err_omp_unexpected_clause_value)
18550             << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18551       } else {
18552         Diag(MLoc, diag::err_omp_unexpected_clause_value)
18553             << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18554         Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18555             << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18556       }
18557       return nullptr;
18558     }
18559 
18560     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18561     //  At most one defaultmap clause for each category can appear on the
18562     //  directive.
18563     if (DSAStack->checkDefaultmapCategory(Kind)) {
18564       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18565       return nullptr;
18566     }
18567   }
18568   if (Kind == OMPC_DEFAULTMAP_unknown) {
18569     // Variable category is not specified - mark all categories.
18570     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18571     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18572     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18573   } else {
18574     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
18575   }
18576 
18577   return new (Context)
18578       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18579 }
18580 
ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)18581 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18582   DeclContext *CurLexicalContext = getCurLexicalContext();
18583   if (!CurLexicalContext->isFileContext() &&
18584       !CurLexicalContext->isExternCContext() &&
18585       !CurLexicalContext->isExternCXXContext() &&
18586       !isa<CXXRecordDecl>(CurLexicalContext) &&
18587       !isa<ClassTemplateDecl>(CurLexicalContext) &&
18588       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18589       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18590     Diag(Loc, diag::err_omp_region_not_file_context);
18591     return false;
18592   }
18593   DeclareTargetNesting.push_back(Loc);
18594   return true;
18595 }
18596 
ActOnFinishOpenMPDeclareTargetDirective()18597 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18598   assert(!DeclareTargetNesting.empty() &&
18599          "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
18600   DeclareTargetNesting.pop_back();
18601 }
18602 
18603 NamedDecl *
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,NamedDeclSetType & SameDirectiveDecls)18604 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18605                                     const DeclarationNameInfo &Id,
18606                                     NamedDeclSetType &SameDirectiveDecls) {
18607   LookupResult Lookup(*this, Id, LookupOrdinaryName);
18608   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18609 
18610   if (Lookup.isAmbiguous())
18611     return nullptr;
18612   Lookup.suppressDiagnostics();
18613 
18614   if (!Lookup.isSingleResult()) {
18615     VarOrFuncDeclFilterCCC CCC(*this);
18616     if (TypoCorrection Corrected =
18617             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18618                         CTK_ErrorRecovery)) {
18619       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18620                                   << Id.getName());
18621       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18622       return nullptr;
18623     }
18624 
18625     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18626     return nullptr;
18627   }
18628 
18629   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18630   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18631       !isa<FunctionTemplateDecl>(ND)) {
18632     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18633     return nullptr;
18634   }
18635   if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18636     Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18637   return ND;
18638 }
18639 
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)18640 void Sema::ActOnOpenMPDeclareTargetName(
18641     NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18642     OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18643   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
18644           isa<FunctionTemplateDecl>(ND)) &&
18645          "Expected variable, function or function template.");
18646 
18647   // Diagnose marking after use as it may lead to incorrect diagnosis and
18648   // codegen.
18649   if (LangOpts.OpenMP >= 50 &&
18650       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18651     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18652 
18653   auto *VD = cast<ValueDecl>(ND);
18654   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18655       OMPDeclareTargetDeclAttr::getDeviceType(VD);
18656   Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD);
18657   if (DevTy.hasValue() && *DevTy != DT &&
18658       (DeclareTargetNesting.empty() ||
18659        *AttrLoc != DeclareTargetNesting.back())) {
18660     Diag(Loc, diag::err_omp_device_type_mismatch)
18661         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18662         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18663     return;
18664   }
18665   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18666       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18667   if (!Res || (!DeclareTargetNesting.empty() &&
18668                *AttrLoc == DeclareTargetNesting.back())) {
18669     auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18670         Context, MT, DT, DeclareTargetNesting.size() + 1,
18671         SourceRange(Loc, Loc));
18672     ND->addAttr(A);
18673     if (ASTMutationListener *ML = Context.getASTMutationListener())
18674       ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18675     checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18676   } else if (*Res != MT) {
18677     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18678   }
18679 }
18680 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)18681 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18682                                      Sema &SemaRef, Decl *D) {
18683   if (!D || !isa<VarDecl>(D))
18684     return;
18685   auto *VD = cast<VarDecl>(D);
18686   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18687       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18688   if (SemaRef.LangOpts.OpenMP >= 50 &&
18689       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18690        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18691       VD->hasGlobalStorage()) {
18692     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18693         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18694     if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18695       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18696       // If a lambda declaration and definition appears between a
18697       // declare target directive and the matching end declare target
18698       // directive, all variables that are captured by the lambda
18699       // expression must also appear in a to clause.
18700       SemaRef.Diag(VD->getLocation(),
18701                    diag::err_omp_lambda_capture_in_declare_target_not_to);
18702       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18703           << VD << 0 << SR;
18704       return;
18705     }
18706   }
18707   if (MapTy.hasValue())
18708     return;
18709   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18710   SemaRef.Diag(SL, diag::note_used_here) << SR;
18711 }
18712 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)18713 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18714                                    Sema &SemaRef, DSAStackTy *Stack,
18715                                    ValueDecl *VD) {
18716   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18717          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18718                            /*FullCheck=*/false);
18719 }
18720 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)18721 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18722                                             SourceLocation IdLoc) {
18723   if (!D || D->isInvalidDecl())
18724     return;
18725   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18726   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18727   if (auto *VD = dyn_cast<VarDecl>(D)) {
18728     // Only global variables can be marked as declare target.
18729     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18730         !VD->isStaticDataMember())
18731       return;
18732     // 2.10.6: threadprivate variable cannot appear in a declare target
18733     // directive.
18734     if (DSAStack->isThreadPrivate(VD)) {
18735       Diag(SL, diag::err_omp_threadprivate_in_target);
18736       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
18737       return;
18738     }
18739   }
18740   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18741     D = FTD->getTemplatedDecl();
18742   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18743     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18744         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18745     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18746       Diag(IdLoc, diag::err_omp_function_in_link_clause);
18747       Diag(FD->getLocation(), diag::note_defined_here) << FD;
18748       return;
18749     }
18750   }
18751   if (auto *VD = dyn_cast<ValueDecl>(D)) {
18752     // Problem if any with var declared with incomplete type will be reported
18753     // as normal, so no need to check it here.
18754     if ((E || !VD->getType()->isIncompleteType()) &&
18755         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
18756       return;
18757     if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18758       // Checking declaration inside declare target region.
18759       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18760           isa<FunctionTemplateDecl>(D)) {
18761         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18762             Context, OMPDeclareTargetDeclAttr::MT_To,
18763             OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(),
18764             SourceRange(DeclareTargetNesting.back(),
18765                         DeclareTargetNesting.back()));
18766         D->addAttr(A);
18767         if (ASTMutationListener *ML = Context.getASTMutationListener())
18768           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18769       }
18770       return;
18771     }
18772   }
18773   if (!E)
18774     return;
18775   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18776 }
18777 
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)18778 OMPClause *Sema::ActOnOpenMPToClause(
18779     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18780     ArrayRef<SourceLocation> MotionModifiersLoc,
18781     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18782     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18783     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18784   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18785                                           OMPC_MOTION_MODIFIER_unknown};
18786   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18787 
18788   // Process motion-modifiers, flag errors for duplicate modifiers.
18789   unsigned Count = 0;
18790   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18791     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18792         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18793       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18794       continue;
18795     }
18796     assert(Count < NumberOfOMPMotionModifiers &&
18797            "Modifiers exceed the allowed number of motion modifiers");
18798     Modifiers[Count] = MotionModifiers[I];
18799     ModifiersLoc[Count] = MotionModifiersLoc[I];
18800     ++Count;
18801   }
18802 
18803   MappableVarListInfo MVLI(VarList);
18804   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
18805                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
18806   if (MVLI.ProcessedVarList.empty())
18807     return nullptr;
18808 
18809   return OMPToClause::Create(
18810       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18811       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18812       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18813 }
18814 
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)18815 OMPClause *Sema::ActOnOpenMPFromClause(
18816     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18817     ArrayRef<SourceLocation> MotionModifiersLoc,
18818     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18819     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18820     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18821   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18822                                           OMPC_MOTION_MODIFIER_unknown};
18823   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18824 
18825   // Process motion-modifiers, flag errors for duplicate modifiers.
18826   unsigned Count = 0;
18827   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18828     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18829         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18830       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18831       continue;
18832     }
18833     assert(Count < NumberOfOMPMotionModifiers &&
18834            "Modifiers exceed the allowed number of motion modifiers");
18835     Modifiers[Count] = MotionModifiers[I];
18836     ModifiersLoc[Count] = MotionModifiersLoc[I];
18837     ++Count;
18838   }
18839 
18840   MappableVarListInfo MVLI(VarList);
18841   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
18842                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
18843   if (MVLI.ProcessedVarList.empty())
18844     return nullptr;
18845 
18846   return OMPFromClause::Create(
18847       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18848       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18849       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18850 }
18851 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)18852 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
18853                                                const OMPVarListLocTy &Locs) {
18854   MappableVarListInfo MVLI(VarList);
18855   SmallVector<Expr *, 8> PrivateCopies;
18856   SmallVector<Expr *, 8> Inits;
18857 
18858   for (Expr *RefExpr : VarList) {
18859     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
18860     SourceLocation ELoc;
18861     SourceRange ERange;
18862     Expr *SimpleRefExpr = RefExpr;
18863     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18864     if (Res.second) {
18865       // It will be analyzed later.
18866       MVLI.ProcessedVarList.push_back(RefExpr);
18867       PrivateCopies.push_back(nullptr);
18868       Inits.push_back(nullptr);
18869     }
18870     ValueDecl *D = Res.first;
18871     if (!D)
18872       continue;
18873 
18874     QualType Type = D->getType();
18875     Type = Type.getNonReferenceType().getUnqualifiedType();
18876 
18877     auto *VD = dyn_cast<VarDecl>(D);
18878 
18879     // Item should be a pointer or reference to pointer.
18880     if (!Type->isPointerType()) {
18881       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
18882           << 0 << RefExpr->getSourceRange();
18883       continue;
18884     }
18885 
18886     // Build the private variable and the expression that refers to it.
18887     auto VDPrivate =
18888         buildVarDecl(*this, ELoc, Type, D->getName(),
18889                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18890                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18891     if (VDPrivate->isInvalidDecl())
18892       continue;
18893 
18894     CurContext->addDecl(VDPrivate);
18895     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18896         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18897 
18898     // Add temporary variable to initialize the private copy of the pointer.
18899     VarDecl *VDInit =
18900         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
18901     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
18902         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
18903     AddInitializerToDecl(VDPrivate,
18904                          DefaultLvalueConversion(VDInitRefExpr).get(),
18905                          /*DirectInit=*/false);
18906 
18907     // If required, build a capture to implement the privatization initialized
18908     // with the current list item value.
18909     DeclRefExpr *Ref = nullptr;
18910     if (!VD)
18911       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18912     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18913     PrivateCopies.push_back(VDPrivateRefExpr);
18914     Inits.push_back(VDInitRefExpr);
18915 
18916     // We need to add a data sharing attribute for this variable to make sure it
18917     // is correctly captured. A variable that shows up in a use_device_ptr has
18918     // similar properties of a first private variable.
18919     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18920 
18921     // Create a mappable component for the list item. List items in this clause
18922     // only need a component.
18923     MVLI.VarBaseDeclarations.push_back(D);
18924     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18925     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
18926                                            /*IsNonContiguous=*/false);
18927   }
18928 
18929   if (MVLI.ProcessedVarList.empty())
18930     return nullptr;
18931 
18932   return OMPUseDevicePtrClause::Create(
18933       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
18934       MVLI.VarBaseDeclarations, MVLI.VarComponents);
18935 }
18936 
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)18937 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
18938                                                 const OMPVarListLocTy &Locs) {
18939   MappableVarListInfo MVLI(VarList);
18940 
18941   for (Expr *RefExpr : VarList) {
18942     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
18943     SourceLocation ELoc;
18944     SourceRange ERange;
18945     Expr *SimpleRefExpr = RefExpr;
18946     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18947                               /*AllowArraySection=*/true);
18948     if (Res.second) {
18949       // It will be analyzed later.
18950       MVLI.ProcessedVarList.push_back(RefExpr);
18951     }
18952     ValueDecl *D = Res.first;
18953     if (!D)
18954       continue;
18955     auto *VD = dyn_cast<VarDecl>(D);
18956 
18957     // If required, build a capture to implement the privatization initialized
18958     // with the current list item value.
18959     DeclRefExpr *Ref = nullptr;
18960     if (!VD)
18961       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18962     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18963 
18964     // We need to add a data sharing attribute for this variable to make sure it
18965     // is correctly captured. A variable that shows up in a use_device_addr has
18966     // similar properties of a first private variable.
18967     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18968 
18969     // Create a mappable component for the list item. List items in this clause
18970     // only need a component.
18971     MVLI.VarBaseDeclarations.push_back(D);
18972     MVLI.VarComponents.emplace_back();
18973     Expr *Component = SimpleRefExpr;
18974     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
18975                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
18976       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
18977     MVLI.VarComponents.back().emplace_back(Component, D,
18978                                            /*IsNonContiguous=*/false);
18979   }
18980 
18981   if (MVLI.ProcessedVarList.empty())
18982     return nullptr;
18983 
18984   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18985                                         MVLI.VarBaseDeclarations,
18986                                         MVLI.VarComponents);
18987 }
18988 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)18989 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
18990                                               const OMPVarListLocTy &Locs) {
18991   MappableVarListInfo MVLI(VarList);
18992   for (Expr *RefExpr : VarList) {
18993     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
18994     SourceLocation ELoc;
18995     SourceRange ERange;
18996     Expr *SimpleRefExpr = RefExpr;
18997     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18998     if (Res.second) {
18999       // It will be analyzed later.
19000       MVLI.ProcessedVarList.push_back(RefExpr);
19001     }
19002     ValueDecl *D = Res.first;
19003     if (!D)
19004       continue;
19005 
19006     QualType Type = D->getType();
19007     // item should be a pointer or array or reference to pointer or array
19008     if (!Type.getNonReferenceType()->isPointerType() &&
19009         !Type.getNonReferenceType()->isArrayType()) {
19010       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
19011           << 0 << RefExpr->getSourceRange();
19012       continue;
19013     }
19014 
19015     // Check if the declaration in the clause does not show up in any data
19016     // sharing attribute.
19017     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19018     if (isOpenMPPrivate(DVar.CKind)) {
19019       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19020           << getOpenMPClauseName(DVar.CKind)
19021           << getOpenMPClauseName(OMPC_is_device_ptr)
19022           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19023       reportOriginalDsa(*this, DSAStack, D, DVar);
19024       continue;
19025     }
19026 
19027     const Expr *ConflictExpr;
19028     if (DSAStack->checkMappableExprComponentListsForDecl(
19029             D, /*CurrentRegionOnly=*/true,
19030             [&ConflictExpr](
19031                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
19032                 OpenMPClauseKind) -> bool {
19033               ConflictExpr = R.front().getAssociatedExpression();
19034               return true;
19035             })) {
19036       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
19037       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
19038           << ConflictExpr->getSourceRange();
19039       continue;
19040     }
19041 
19042     // Store the components in the stack so that they can be used to check
19043     // against other clauses later on.
19044     OMPClauseMappableExprCommon::MappableComponent MC(
19045         SimpleRefExpr, D, /*IsNonContiguous=*/false);
19046     DSAStack->addMappableExpressionComponents(
19047         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
19048 
19049     // Record the expression we've just processed.
19050     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
19051 
19052     // Create a mappable component for the list item. List items in this clause
19053     // only need a component. We use a null declaration to signal fields in
19054     // 'this'.
19055     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
19056             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
19057            "Unexpected device pointer expression!");
19058     MVLI.VarBaseDeclarations.push_back(
19059         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
19060     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19061     MVLI.VarComponents.back().push_back(MC);
19062   }
19063 
19064   if (MVLI.ProcessedVarList.empty())
19065     return nullptr;
19066 
19067   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
19068                                       MVLI.VarBaseDeclarations,
19069                                       MVLI.VarComponents);
19070 }
19071 
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19072 OMPClause *Sema::ActOnOpenMPAllocateClause(
19073     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19074     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
19075   if (Allocator) {
19076     // OpenMP [2.11.4 allocate Clause, Description]
19077     // allocator is an expression of omp_allocator_handle_t type.
19078     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
19079       return nullptr;
19080 
19081     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
19082     if (AllocatorRes.isInvalid())
19083       return nullptr;
19084     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
19085                                              DSAStack->getOMPAllocatorHandleT(),
19086                                              Sema::AA_Initializing,
19087                                              /*AllowExplicit=*/true);
19088     if (AllocatorRes.isInvalid())
19089       return nullptr;
19090     Allocator = AllocatorRes.get();
19091   } else {
19092     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
19093     // allocate clauses that appear on a target construct or on constructs in a
19094     // target region must specify an allocator expression unless a requires
19095     // directive with the dynamic_allocators clause is present in the same
19096     // compilation unit.
19097     if (LangOpts.OpenMPIsDevice &&
19098         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
19099       targetDiag(StartLoc, diag::err_expected_allocator_expression);
19100   }
19101   // Analyze and build list of variables.
19102   SmallVector<Expr *, 8> Vars;
19103   for (Expr *RefExpr : VarList) {
19104     assert(RefExpr && "NULL expr in OpenMP private clause.");
19105     SourceLocation ELoc;
19106     SourceRange ERange;
19107     Expr *SimpleRefExpr = RefExpr;
19108     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19109     if (Res.second) {
19110       // It will be analyzed later.
19111       Vars.push_back(RefExpr);
19112     }
19113     ValueDecl *D = Res.first;
19114     if (!D)
19115       continue;
19116 
19117     auto *VD = dyn_cast<VarDecl>(D);
19118     DeclRefExpr *Ref = nullptr;
19119     if (!VD && !CurContext->isDependentContext())
19120       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19121     Vars.push_back((VD || CurContext->isDependentContext())
19122                        ? RefExpr->IgnoreParens()
19123                        : Ref);
19124   }
19125 
19126   if (Vars.empty())
19127     return nullptr;
19128 
19129   if (Allocator)
19130     DSAStack->addInnerAllocatorExpr(Allocator);
19131   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
19132                                    ColonLoc, EndLoc, Vars);
19133 }
19134 
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19135 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
19136                                               SourceLocation StartLoc,
19137                                               SourceLocation LParenLoc,
19138                                               SourceLocation EndLoc) {
19139   SmallVector<Expr *, 8> Vars;
19140   for (Expr *RefExpr : VarList) {
19141     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19142     SourceLocation ELoc;
19143     SourceRange ERange;
19144     Expr *SimpleRefExpr = RefExpr;
19145     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19146     if (Res.second)
19147       // It will be analyzed later.
19148       Vars.push_back(RefExpr);
19149     ValueDecl *D = Res.first;
19150     if (!D)
19151       continue;
19152 
19153     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
19154     // A list-item cannot appear in more than one nontemporal clause.
19155     if (const Expr *PrevRef =
19156             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
19157       Diag(ELoc, diag::err_omp_used_in_clause_twice)
19158           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
19159       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19160           << getOpenMPClauseName(OMPC_nontemporal);
19161       continue;
19162     }
19163 
19164     Vars.push_back(RefExpr);
19165   }
19166 
19167   if (Vars.empty())
19168     return nullptr;
19169 
19170   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19171                                       Vars);
19172 }
19173 
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19174 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
19175                                             SourceLocation StartLoc,
19176                                             SourceLocation LParenLoc,
19177                                             SourceLocation EndLoc) {
19178   SmallVector<Expr *, 8> Vars;
19179   for (Expr *RefExpr : VarList) {
19180     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19181     SourceLocation ELoc;
19182     SourceRange ERange;
19183     Expr *SimpleRefExpr = RefExpr;
19184     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19185                               /*AllowArraySection=*/true);
19186     if (Res.second)
19187       // It will be analyzed later.
19188       Vars.push_back(RefExpr);
19189     ValueDecl *D = Res.first;
19190     if (!D)
19191       continue;
19192 
19193     const DSAStackTy::DSAVarData DVar =
19194         DSAStack->getTopDSA(D, /*FromParent=*/true);
19195     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19196     // A list item that appears in the inclusive or exclusive clause must appear
19197     // in a reduction clause with the inscan modifier on the enclosing
19198     // worksharing-loop, worksharing-loop SIMD, or simd construct.
19199     if (DVar.CKind != OMPC_reduction ||
19200         DVar.Modifier != OMPC_REDUCTION_inscan)
19201       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19202           << RefExpr->getSourceRange();
19203 
19204     if (DSAStack->getParentDirective() != OMPD_unknown)
19205       DSAStack->markDeclAsUsedInScanDirective(D);
19206     Vars.push_back(RefExpr);
19207   }
19208 
19209   if (Vars.empty())
19210     return nullptr;
19211 
19212   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19213 }
19214 
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19215 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19216                                             SourceLocation StartLoc,
19217                                             SourceLocation LParenLoc,
19218                                             SourceLocation EndLoc) {
19219   SmallVector<Expr *, 8> Vars;
19220   for (Expr *RefExpr : VarList) {
19221     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
19222     SourceLocation ELoc;
19223     SourceRange ERange;
19224     Expr *SimpleRefExpr = RefExpr;
19225     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19226                               /*AllowArraySection=*/true);
19227     if (Res.second)
19228       // It will be analyzed later.
19229       Vars.push_back(RefExpr);
19230     ValueDecl *D = Res.first;
19231     if (!D)
19232       continue;
19233 
19234     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
19235     DSAStackTy::DSAVarData DVar;
19236     if (ParentDirective != OMPD_unknown)
19237       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
19238     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19239     // A list item that appears in the inclusive or exclusive clause must appear
19240     // in a reduction clause with the inscan modifier on the enclosing
19241     // worksharing-loop, worksharing-loop SIMD, or simd construct.
19242     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19243         DVar.Modifier != OMPC_REDUCTION_inscan) {
19244       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19245           << RefExpr->getSourceRange();
19246     } else {
19247       DSAStack->markDeclAsUsedInScanDirective(D);
19248     }
19249     Vars.push_back(RefExpr);
19250   }
19251 
19252   if (Vars.empty())
19253     return nullptr;
19254 
19255   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19256 }
19257 
19258 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)19259 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19260   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19261   if (!OMPAlloctraitT.isNull())
19262     return true;
19263   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19264   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19265   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19266     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19267     return false;
19268   }
19269   Stack->setOMPAlloctraitT(PT.get());
19270   return true;
19271 }
19272 
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)19273 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19274     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19275     ArrayRef<UsesAllocatorsData> Data) {
19276   // OpenMP [2.12.5, target Construct]
19277   // allocator is an identifier of omp_allocator_handle_t type.
19278   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
19279     return nullptr;
19280   // OpenMP [2.12.5, target Construct]
19281   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19282   if (llvm::any_of(
19283           Data,
19284           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19285       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
19286     return nullptr;
19287   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19288   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19289     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19290     StringRef Allocator =
19291         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19292     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19293     PredefinedAllocators.insert(LookupSingleName(
19294         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19295   }
19296 
19297   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19298   for (const UsesAllocatorsData &D : Data) {
19299     Expr *AllocatorExpr = nullptr;
19300     // Check allocator expression.
19301     if (D.Allocator->isTypeDependent()) {
19302       AllocatorExpr = D.Allocator;
19303     } else {
19304       // Traits were specified - need to assign new allocator to the specified
19305       // allocator, so it must be an lvalue.
19306       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19307       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19308       bool IsPredefinedAllocator = false;
19309       if (DRE)
19310         IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19311       if (!DRE ||
19312           !(Context.hasSameUnqualifiedType(
19313                 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
19314             Context.typesAreCompatible(AllocatorExpr->getType(),
19315                                        DSAStack->getOMPAllocatorHandleT(),
19316                                        /*CompareUnqualified=*/true)) ||
19317           (!IsPredefinedAllocator &&
19318            (AllocatorExpr->getType().isConstant(Context) ||
19319             !AllocatorExpr->isLValue()))) {
19320         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19321             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19322             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19323         continue;
19324       }
19325       // OpenMP [2.12.5, target Construct]
19326       // Predefined allocators appearing in a uses_allocators clause cannot have
19327       // traits specified.
19328       if (IsPredefinedAllocator && D.AllocatorTraits) {
19329         Diag(D.AllocatorTraits->getExprLoc(),
19330              diag::err_omp_predefined_allocator_with_traits)
19331             << D.AllocatorTraits->getSourceRange();
19332         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19333             << cast<NamedDecl>(DRE->getDecl())->getName()
19334             << D.Allocator->getSourceRange();
19335         continue;
19336       }
19337       // OpenMP [2.12.5, target Construct]
19338       // Non-predefined allocators appearing in a uses_allocators clause must
19339       // have traits specified.
19340       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19341         Diag(D.Allocator->getExprLoc(),
19342              diag::err_omp_nonpredefined_allocator_without_traits);
19343         continue;
19344       }
19345       // No allocator traits - just convert it to rvalue.
19346       if (!D.AllocatorTraits)
19347         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19348       DSAStack->addUsesAllocatorsDecl(
19349           DRE->getDecl(),
19350           IsPredefinedAllocator
19351               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19352               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19353     }
19354     Expr *AllocatorTraitsExpr = nullptr;
19355     if (D.AllocatorTraits) {
19356       if (D.AllocatorTraits->isTypeDependent()) {
19357         AllocatorTraitsExpr = D.AllocatorTraits;
19358       } else {
19359         // OpenMP [2.12.5, target Construct]
19360         // Arrays that contain allocator traits that appear in a uses_allocators
19361         // clause must be constant arrays, have constant values and be defined
19362         // in the same scope as the construct in which the clause appears.
19363         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19364         // Check that traits expr is a constant array.
19365         QualType TraitTy;
19366         if (const ArrayType *Ty =
19367                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19368           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19369             TraitTy = ConstArrayTy->getElementType();
19370         if (TraitTy.isNull() ||
19371             !(Context.hasSameUnqualifiedType(TraitTy,
19372                                              DSAStack->getOMPAlloctraitT()) ||
19373               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
19374                                          /*CompareUnqualified=*/true))) {
19375           Diag(D.AllocatorTraits->getExprLoc(),
19376                diag::err_omp_expected_array_alloctraits)
19377               << AllocatorTraitsExpr->getType();
19378           continue;
19379         }
19380         // Do not map by default allocator traits if it is a standalone
19381         // variable.
19382         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19383           DSAStack->addUsesAllocatorsDecl(
19384               DRE->getDecl(),
19385               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19386       }
19387     }
19388     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19389     NewD.Allocator = AllocatorExpr;
19390     NewD.AllocatorTraits = AllocatorTraitsExpr;
19391     NewD.LParenLoc = D.LParenLoc;
19392     NewD.RParenLoc = D.RParenLoc;
19393   }
19394   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19395                                          NewData);
19396 }
19397 
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)19398 OMPClause *Sema::ActOnOpenMPAffinityClause(
19399     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19400     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19401   SmallVector<Expr *, 8> Vars;
19402   for (Expr *RefExpr : Locators) {
19403     assert(RefExpr && "NULL expr in OpenMP shared clause.");
19404     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19405       // It will be analyzed later.
19406       Vars.push_back(RefExpr);
19407       continue;
19408     }
19409 
19410     SourceLocation ELoc = RefExpr->getExprLoc();
19411     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19412 
19413     if (!SimpleExpr->isLValue()) {
19414       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19415           << 1 << 0 << RefExpr->getSourceRange();
19416       continue;
19417     }
19418 
19419     ExprResult Res;
19420     {
19421       Sema::TentativeAnalysisScope Trap(*this);
19422       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19423     }
19424     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19425         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19426       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19427           << 1 << 0 << RefExpr->getSourceRange();
19428       continue;
19429     }
19430     Vars.push_back(SimpleExpr);
19431   }
19432 
19433   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19434                                    EndLoc, Modifier, Vars);
19435 }
19436