1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/ASTMutationListener.h"
18 #include "clang/AST/CXXInheritance.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/Basic/OpenMPKinds.h"
26 #include "clang/Sema/Initialization.h"
27 #include "clang/Sema/Lookup.h"
28 #include "clang/Sema/Scope.h"
29 #include "clang/Sema/ScopeInfo.h"
30 #include "clang/Sema/SemaInternal.h"
31 #include "llvm/ADT/PointerEmbeddedInt.h"
32 using namespace clang;
33 
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
37 
38 static const Expr *checkMapClauseExpressionBase(
39     Sema &SemaRef, Expr *E,
40     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
41     OpenMPClauseKind CKind, bool NoDiagnose);
42 
43 namespace {
44 /// Default data sharing attributes, which can be applied to directive.
45 enum DefaultDataSharingAttributes {
46   DSA_unspecified = 0, /// Data sharing attribute not specified.
47   DSA_none = 1 << 0,   /// Default data sharing attribute 'none'.
48   DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
49 };
50 
51 /// Attributes of the defaultmap clause.
52 enum DefaultMapAttributes {
53   DMA_unspecified,   /// Default mapping is not specified.
54   DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
55 };
56 
57 /// Stack for tracking declarations used in OpenMP directives and
58 /// clauses and their data-sharing attributes.
59 class DSAStackTy {
60 public:
61   struct DSAVarData {
62     OpenMPDirectiveKind DKind = OMPD_unknown;
63     OpenMPClauseKind CKind = OMPC_unknown;
64     const Expr *RefExpr = nullptr;
65     DeclRefExpr *PrivateCopy = nullptr;
66     SourceLocation ImplicitDSALoc;
67     DSAVarData() = default;
DSAVarData__anon0050f7f00111::DSAStackTy::DSAVarData68     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
69                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
70                SourceLocation ImplicitDSALoc)
71         : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73   };
74   using OperatorOffsetTy =
75       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
76   using DoacrossDependMapTy =
77       llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
78 
79 private:
80   struct DSAInfo {
81     OpenMPClauseKind Attributes = OMPC_unknown;
82     /// Pointer to a reference expression and a flag which shows that the
83     /// variable is marked as lastprivate(true) or not (false).
84     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
85     DeclRefExpr *PrivateCopy = nullptr;
86   };
87   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88   using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90   using LoopControlVariablesMapTy =
91       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92   /// Struct that associates a component with the clause kind where they are
93   /// found.
94   struct MappedExprComponentTy {
95     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
96     OpenMPClauseKind Kind = OMPC_unknown;
97   };
98   using MappedExprComponentsTy =
99       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100   using CriticalsWithHintsTy =
101       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102   struct ReductionData {
103     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
104     SourceRange ReductionRange;
105     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106     ReductionData() = default;
set__anon0050f7f00111::DSAStackTy::ReductionData107     void set(BinaryOperatorKind BO, SourceRange RR) {
108       ReductionRange = RR;
109       ReductionOp = BO;
110     }
set__anon0050f7f00111::DSAStackTy::ReductionData111     void set(const Expr *RefExpr, SourceRange RR) {
112       ReductionRange = RR;
113       ReductionOp = RefExpr;
114     }
115   };
116   using DeclReductionMapTy =
117       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
118 
119   struct SharingMapTy {
120     DeclSAMapTy SharingMap;
121     DeclReductionMapTy ReductionMap;
122     AlignedMapTy AlignedMap;
123     MappedExprComponentsTy MappedExprComponents;
124     LoopControlVariablesMapTy LCVMap;
125     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
126     SourceLocation DefaultAttrLoc;
127     DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
128     SourceLocation DefaultMapAttrLoc;
129     OpenMPDirectiveKind Directive = OMPD_unknown;
130     DeclarationNameInfo DirectiveName;
131     Scope *CurScope = nullptr;
132     SourceLocation ConstructLoc;
133     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
134     /// get the data (loop counters etc.) about enclosing loop-based construct.
135     /// This data is required during codegen.
136     DoacrossDependMapTy DoacrossDepends;
137     /// first argument (Expr *) contains optional argument of the
138     /// 'ordered' clause, the second one is true if the regions has 'ordered'
139     /// clause, false otherwise.
140     llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
141     bool NowaitRegion = false;
142     bool CancelRegion = false;
143     unsigned AssociatedLoops = 1;
144     SourceLocation InnerTeamsRegionLoc;
145     /// Reference to the taskgroup task_reduction reference expression.
146     Expr *TaskgroupReductionRef = nullptr;
SharingMapTy__anon0050f7f00111::DSAStackTy::SharingMapTy147     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
148                  Scope *CurScope, SourceLocation Loc)
149         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
150           ConstructLoc(Loc) {}
151     SharingMapTy() = default;
152   };
153 
154   using StackTy = SmallVector<SharingMapTy, 4>;
155 
156   /// Stack of used declaration and their data-sharing attributes.
157   DeclSAMapTy Threadprivates;
158   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
159   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
160   /// true, if check for DSA must be from parent directive, false, if
161   /// from current directive.
162   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
163   Sema &SemaRef;
164   bool ForceCapturing = false;
165   CriticalsWithHintsTy Criticals;
166 
167   using iterator = StackTy::const_reverse_iterator;
168 
169   DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
170 
171   /// Checks if the variable is a local for OpenMP region.
172   bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
173 
isStackEmpty() const174   bool isStackEmpty() const {
175     return Stack.empty() ||
176            Stack.back().second != CurrentNonCapturingFunctionScope ||
177            Stack.back().first.empty();
178   }
179 
180 public:
DSAStackTy(Sema & S)181   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
182 
isClauseParsingMode() const183   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const184   OpenMPClauseKind getClauseParsingMode() const {
185     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
186     return ClauseKindMode;
187   }
setClauseParsingMode(OpenMPClauseKind K)188   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
189 
isForceVarCapturing() const190   bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)191   void setForceVarCapturing(bool V) { ForceCapturing = V; }
192 
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)193   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
194             Scope *CurScope, SourceLocation Loc) {
195     if (Stack.empty() ||
196         Stack.back().second != CurrentNonCapturingFunctionScope)
197       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
198     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
199     Stack.back().first.back().DefaultAttrLoc = Loc;
200   }
201 
pop()202   void pop() {
203     assert(!Stack.back().first.empty() &&
204            "Data-sharing attributes stack is empty!");
205     Stack.back().first.pop_back();
206   }
207 
208   /// Start new OpenMP region stack in new non-capturing function.
pushFunction()209   void pushFunction() {
210     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
211     assert(!isa<CapturingScopeInfo>(CurFnScope));
212     CurrentNonCapturingFunctionScope = CurFnScope;
213   }
214   /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)215   void popFunction(const FunctionScopeInfo *OldFSI) {
216     if (!Stack.empty() && Stack.back().second == OldFSI) {
217       assert(Stack.back().first.empty());
218       Stack.pop_back();
219     }
220     CurrentNonCapturingFunctionScope = nullptr;
221     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
222       if (!isa<CapturingScopeInfo>(FSI)) {
223         CurrentNonCapturingFunctionScope = FSI;
224         break;
225       }
226     }
227   }
228 
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)229   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
230     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
231   }
232   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const233   getCriticalWithHint(const DeclarationNameInfo &Name) const {
234     auto I = Criticals.find(Name.getAsString());
235     if (I != Criticals.end())
236       return I->second;
237     return std::make_pair(nullptr, llvm::APSInt());
238   }
239   /// If 'aligned' declaration for given variable \a D was not seen yet,
240   /// add it and return NULL; otherwise return previous occurrence's expression
241   /// for diagnostics.
242   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
243 
244   /// Register specified variable as loop control variable.
245   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
246   /// Check if the specified variable is a loop control variable for
247   /// current region.
248   /// \return The index of the loop control variable in the list of associated
249   /// for-loops (from outer to inner).
250   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
251   /// Check if the specified variable is a loop control variable for
252   /// parent region.
253   /// \return The index of the loop control variable in the list of associated
254   /// for-loops (from outer to inner).
255   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
256   /// Get the loop control variable for the I-th loop (or nullptr) in
257   /// parent directive.
258   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
259 
260   /// Adds explicit data sharing attribute to the specified declaration.
261   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
262               DeclRefExpr *PrivateCopy = nullptr);
263 
264   /// Adds additional information for the reduction items with the reduction id
265   /// represented as an operator.
266   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
267                                  BinaryOperatorKind BOK);
268   /// Adds additional information for the reduction items with the reduction id
269   /// represented as reduction identifier.
270   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
271                                  const Expr *ReductionRef);
272   /// Returns the location and reduction operation from the innermost parent
273   /// region for the given \p D.
274   const DSAVarData
275   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
276                                    BinaryOperatorKind &BOK,
277                                    Expr *&TaskgroupDescriptor) const;
278   /// Returns the location and reduction operation from the innermost parent
279   /// region for the given \p D.
280   const DSAVarData
281   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
282                                    const Expr *&ReductionRef,
283                                    Expr *&TaskgroupDescriptor) const;
284   /// Return reduction reference expression for the current taskgroup.
getTaskgroupReductionRef() const285   Expr *getTaskgroupReductionRef() const {
286     assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
287            "taskgroup reference expression requested for non taskgroup "
288            "directive.");
289     return Stack.back().first.back().TaskgroupReductionRef;
290   }
291   /// Checks if the given \p VD declaration is actually a taskgroup reduction
292   /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const293   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
294     return Stack.back().first[Level].TaskgroupReductionRef &&
295            cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
296                    ->getDecl() == VD;
297   }
298 
299   /// Returns data sharing attributes from top of the stack for the
300   /// specified declaration.
301   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
302   /// Returns data-sharing attributes for the specified declaration.
303   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
304   /// Checks if the specified variables has data-sharing attributes which
305   /// match specified \a CPred predicate in any directive which matches \a DPred
306   /// predicate.
307   const DSAVarData
308   hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
309          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
310          bool FromParent) const;
311   /// Checks if the specified variables has data-sharing attributes which
312   /// match specified \a CPred predicate in any innermost directive which
313   /// matches \a DPred predicate.
314   const DSAVarData
315   hasInnermostDSA(ValueDecl *D,
316                   const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
317                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
318                   bool FromParent) const;
319   /// Checks if the specified variables has explicit data-sharing
320   /// attributes which match specified \a CPred predicate at the specified
321   /// OpenMP region.
322   bool hasExplicitDSA(const ValueDecl *D,
323                       const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
324                       unsigned Level, bool NotLastprivate = false) const;
325 
326   /// Returns true if the directive at level \Level matches in the
327   /// specified \a DPred predicate.
328   bool hasExplicitDirective(
329       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
330       unsigned Level) const;
331 
332   /// Finds a directive which matches specified \a DPred predicate.
333   bool hasDirective(
334       const llvm::function_ref<bool(
335           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
336           DPred,
337       bool FromParent) const;
338 
339   /// Returns currently analyzed directive.
getCurrentDirective() const340   OpenMPDirectiveKind getCurrentDirective() const {
341     return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
342   }
343   /// Returns directive kind at specified level.
getDirective(unsigned Level) const344   OpenMPDirectiveKind getDirective(unsigned Level) const {
345     assert(!isStackEmpty() && "No directive at specified level.");
346     return Stack.back().first[Level].Directive;
347   }
348   /// Returns parent directive.
getParentDirective() const349   OpenMPDirectiveKind getParentDirective() const {
350     if (isStackEmpty() || Stack.back().first.size() == 1)
351       return OMPD_unknown;
352     return std::next(Stack.back().first.rbegin())->Directive;
353   }
354 
355   /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)356   void setDefaultDSANone(SourceLocation Loc) {
357     assert(!isStackEmpty());
358     Stack.back().first.back().DefaultAttr = DSA_none;
359     Stack.back().first.back().DefaultAttrLoc = Loc;
360   }
361   /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)362   void setDefaultDSAShared(SourceLocation Loc) {
363     assert(!isStackEmpty());
364     Stack.back().first.back().DefaultAttr = DSA_shared;
365     Stack.back().first.back().DefaultAttrLoc = Loc;
366   }
367   /// Set default data mapping attribute to 'tofrom:scalar'.
setDefaultDMAToFromScalar(SourceLocation Loc)368   void setDefaultDMAToFromScalar(SourceLocation Loc) {
369     assert(!isStackEmpty());
370     Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
371     Stack.back().first.back().DefaultMapAttrLoc = Loc;
372   }
373 
getDefaultDSA() const374   DefaultDataSharingAttributes getDefaultDSA() const {
375     return isStackEmpty() ? DSA_unspecified
376                           : Stack.back().first.back().DefaultAttr;
377   }
getDefaultDSALocation() const378   SourceLocation getDefaultDSALocation() const {
379     return isStackEmpty() ? SourceLocation()
380                           : Stack.back().first.back().DefaultAttrLoc;
381   }
getDefaultDMA() const382   DefaultMapAttributes getDefaultDMA() const {
383     return isStackEmpty() ? DMA_unspecified
384                           : Stack.back().first.back().DefaultMapAttr;
385   }
getDefaultDMAAtLevel(unsigned Level) const386   DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
387     return Stack.back().first[Level].DefaultMapAttr;
388   }
getDefaultDMALocation() const389   SourceLocation getDefaultDMALocation() const {
390     return isStackEmpty() ? SourceLocation()
391                           : Stack.back().first.back().DefaultMapAttrLoc;
392   }
393 
394   /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)395   bool isThreadPrivate(VarDecl *D) {
396     const DSAVarData DVar = getTopDSA(D, false);
397     return isOpenMPThreadPrivate(DVar.CKind);
398   }
399 
400   /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)401   void setOrderedRegion(bool IsOrdered, const Expr *Param,
402                         OMPOrderedClause *Clause) {
403     assert(!isStackEmpty());
404     if (IsOrdered)
405       Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
406     else
407       Stack.back().first.back().OrderedRegion.reset();
408   }
409   /// Returns true, if region is ordered (has associated 'ordered' clause),
410   /// false - otherwise.
isOrderedRegion() const411   bool isOrderedRegion() const {
412     if (isStackEmpty())
413       return false;
414     return Stack.back().first.rbegin()->OrderedRegion.hasValue();
415   }
416   /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const417   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
418     if (isStackEmpty() ||
419         !Stack.back().first.rbegin()->OrderedRegion.hasValue())
420       return std::make_pair(nullptr, nullptr);
421     return Stack.back().first.rbegin()->OrderedRegion.getValue();
422   }
423   /// Returns true, if parent region is ordered (has associated
424   /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const425   bool isParentOrderedRegion() const {
426     if (isStackEmpty() || Stack.back().first.size() == 1)
427       return false;
428     return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
429   }
430   /// Returns optional parameter for the ordered region.
431   std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const432   getParentOrderedRegionParam() const {
433     if (isStackEmpty() || Stack.back().first.size() == 1 ||
434         !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
435       return std::make_pair(nullptr, nullptr);
436     return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
437   }
438   /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)439   void setNowaitRegion(bool IsNowait = true) {
440     assert(!isStackEmpty());
441     Stack.back().first.back().NowaitRegion = IsNowait;
442   }
443   /// Returns true, if parent region is nowait (has associated
444   /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const445   bool isParentNowaitRegion() const {
446     if (isStackEmpty() || Stack.back().first.size() == 1)
447       return false;
448     return std::next(Stack.back().first.rbegin())->NowaitRegion;
449   }
450   /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)451   void setParentCancelRegion(bool Cancel = true) {
452     if (!isStackEmpty() && Stack.back().first.size() > 1) {
453       auto &StackElemRef = *std::next(Stack.back().first.rbegin());
454       StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
455     }
456   }
457   /// Return true if current region has inner cancel construct.
isCancelRegion() const458   bool isCancelRegion() const {
459     return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
460   }
461 
462   /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)463   void setAssociatedLoops(unsigned Val) {
464     assert(!isStackEmpty());
465     Stack.back().first.back().AssociatedLoops = Val;
466   }
467   /// Return collapse value for region.
getAssociatedLoops() const468   unsigned getAssociatedLoops() const {
469     return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
470   }
471 
472   /// Marks current target region as one with closely nested teams
473   /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)474   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
475     if (!isStackEmpty() && Stack.back().first.size() > 1) {
476       std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
477           TeamsRegionLoc;
478     }
479   }
480   /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const481   bool hasInnerTeamsRegion() const {
482     return getInnerTeamsRegionLoc().isValid();
483   }
484   /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const485   SourceLocation getInnerTeamsRegionLoc() const {
486     return isStackEmpty() ? SourceLocation()
487                           : Stack.back().first.back().InnerTeamsRegionLoc;
488   }
489 
getCurScope() const490   Scope *getCurScope() const {
491     return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
492   }
getConstructLoc() const493   SourceLocation getConstructLoc() const {
494     return isStackEmpty() ? SourceLocation()
495                           : Stack.back().first.back().ConstructLoc;
496   }
497 
498   /// Do the check specified in \a Check to all component lists and return true
499   /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const500   bool checkMappableExprComponentListsForDecl(
501       const ValueDecl *VD, bool CurrentRegionOnly,
502       const llvm::function_ref<
503           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
504                OpenMPClauseKind)>
505           Check) const {
506     if (isStackEmpty())
507       return false;
508     auto SI = Stack.back().first.rbegin();
509     auto SE = Stack.back().first.rend();
510 
511     if (SI == SE)
512       return false;
513 
514     if (CurrentRegionOnly)
515       SE = std::next(SI);
516     else
517       std::advance(SI, 1);
518 
519     for (; SI != SE; ++SI) {
520       auto MI = SI->MappedExprComponents.find(VD);
521       if (MI != SI->MappedExprComponents.end())
522         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
523              MI->second.Components)
524           if (Check(L, MI->second.Kind))
525             return true;
526     }
527     return false;
528   }
529 
530   /// Do the check specified in \a Check to all component lists at a given level
531   /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const532   bool checkMappableExprComponentListsForDeclAtLevel(
533       const ValueDecl *VD, unsigned Level,
534       const llvm::function_ref<
535           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
536                OpenMPClauseKind)>
537           Check) const {
538     if (isStackEmpty())
539       return false;
540 
541     auto StartI = Stack.back().first.begin();
542     auto EndI = Stack.back().first.end();
543     if (std::distance(StartI, EndI) <= (int)Level)
544       return false;
545     std::advance(StartI, Level);
546 
547     auto MI = StartI->MappedExprComponents.find(VD);
548     if (MI != StartI->MappedExprComponents.end())
549       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
550            MI->second.Components)
551         if (Check(L, MI->second.Kind))
552           return true;
553     return false;
554   }
555 
556   /// Create a new mappable expression component list associated with a given
557   /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)558   void addMappableExpressionComponents(
559       const ValueDecl *VD,
560       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
561       OpenMPClauseKind WhereFoundClauseKind) {
562     assert(!isStackEmpty() &&
563            "Not expecting to retrieve components from a empty stack!");
564     MappedExprComponentTy &MEC =
565         Stack.back().first.back().MappedExprComponents[VD];
566     // Create new entry and append the new components there.
567     MEC.Components.resize(MEC.Components.size() + 1);
568     MEC.Components.back().append(Components.begin(), Components.end());
569     MEC.Kind = WhereFoundClauseKind;
570   }
571 
getNestingLevel() const572   unsigned getNestingLevel() const {
573     assert(!isStackEmpty());
574     return Stack.back().first.size() - 1;
575   }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)576   void addDoacrossDependClause(OMPDependClause *C,
577                                const OperatorOffsetTy &OpsOffs) {
578     assert(!isStackEmpty() && Stack.back().first.size() > 1);
579     SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
580     assert(isOpenMPWorksharingDirective(StackElem.Directive));
581     StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
582   }
583   llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const584   getDoacrossDependClauses() const {
585     assert(!isStackEmpty());
586     const SharingMapTy &StackElem = Stack.back().first.back();
587     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
588       const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
589       return llvm::make_range(Ref.begin(), Ref.end());
590     }
591     return llvm::make_range(StackElem.DoacrossDepends.end(),
592                             StackElem.DoacrossDepends.end());
593   }
594 };
isParallelOrTaskRegion(OpenMPDirectiveKind DKind)595 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
596   return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
597          isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
598 }
599 
600 } // namespace
601 
getExprAsWritten(const Expr * E)602 static const Expr *getExprAsWritten(const Expr *E) {
603   if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
604     E = ExprTemp->getSubExpr();
605 
606   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
607     E = MTE->GetTemporaryExpr();
608 
609   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
610     E = Binder->getSubExpr();
611 
612   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
613     E = ICE->getSubExprAsWritten();
614   return E->IgnoreParens();
615 }
616 
getExprAsWritten(Expr * E)617 static Expr *getExprAsWritten(Expr *E) {
618   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
619 }
620 
getCanonicalDecl(const ValueDecl * D)621 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
622   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
623     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
624       D = ME->getMemberDecl();
625   const auto *VD = dyn_cast<VarDecl>(D);
626   const auto *FD = dyn_cast<FieldDecl>(D);
627   if (VD != nullptr) {
628     VD = VD->getCanonicalDecl();
629     D = VD;
630   } else {
631     assert(FD);
632     FD = FD->getCanonicalDecl();
633     D = FD;
634   }
635   return D;
636 }
637 
getCanonicalDecl(ValueDecl * D)638 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
639   return const_cast<ValueDecl *>(
640       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
641 }
642 
getDSA(iterator & Iter,ValueDecl * D) const643 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
644                                           ValueDecl *D) const {
645   D = getCanonicalDecl(D);
646   auto *VD = dyn_cast<VarDecl>(D);
647   const auto *FD = dyn_cast<FieldDecl>(D);
648   DSAVarData DVar;
649   if (isStackEmpty() || Iter == Stack.back().first.rend()) {
650     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
651     // in a region but not in construct]
652     //  File-scope or namespace-scope variables referenced in called routines
653     //  in the region are shared unless they appear in a threadprivate
654     //  directive.
655     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
656       DVar.CKind = OMPC_shared;
657 
658     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
659     // in a region but not in construct]
660     //  Variables with static storage duration that are declared in called
661     //  routines in the region are shared.
662     if (VD && VD->hasGlobalStorage())
663       DVar.CKind = OMPC_shared;
664 
665     // Non-static data members are shared by default.
666     if (FD)
667       DVar.CKind = OMPC_shared;
668 
669     return DVar;
670   }
671 
672   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
673   // in a Construct, C/C++, predetermined, p.1]
674   // Variables with automatic storage duration that are declared in a scope
675   // inside the construct are private.
676   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
677       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
678     DVar.CKind = OMPC_private;
679     return DVar;
680   }
681 
682   DVar.DKind = Iter->Directive;
683   // Explicitly specified attributes and local variables with predetermined
684   // attributes.
685   if (Iter->SharingMap.count(D)) {
686     const DSAInfo &Data = Iter->SharingMap.lookup(D);
687     DVar.RefExpr = Data.RefExpr.getPointer();
688     DVar.PrivateCopy = Data.PrivateCopy;
689     DVar.CKind = Data.Attributes;
690     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
691     return DVar;
692   }
693 
694   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
695   // in a Construct, C/C++, implicitly determined, p.1]
696   //  In a parallel or task construct, the data-sharing attributes of these
697   //  variables are determined by the default clause, if present.
698   switch (Iter->DefaultAttr) {
699   case DSA_shared:
700     DVar.CKind = OMPC_shared;
701     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
702     return DVar;
703   case DSA_none:
704     return DVar;
705   case DSA_unspecified:
706     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
707     // in a Construct, implicitly determined, p.2]
708     //  In a parallel construct, if no default clause is present, these
709     //  variables are shared.
710     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
711     if (isOpenMPParallelDirective(DVar.DKind) ||
712         isOpenMPTeamsDirective(DVar.DKind)) {
713       DVar.CKind = OMPC_shared;
714       return DVar;
715     }
716 
717     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
718     // in a Construct, implicitly determined, p.4]
719     //  In a task construct, if no default clause is present, a variable that in
720     //  the enclosing context is determined to be shared by all implicit tasks
721     //  bound to the current team is shared.
722     if (isOpenMPTaskingDirective(DVar.DKind)) {
723       DSAVarData DVarTemp;
724       iterator I = Iter, E = Stack.back().first.rend();
725       do {
726         ++I;
727         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
728         // Referenced in a Construct, implicitly determined, p.6]
729         //  In a task construct, if no default clause is present, a variable
730         //  whose data-sharing attribute is not determined by the rules above is
731         //  firstprivate.
732         DVarTemp = getDSA(I, D);
733         if (DVarTemp.CKind != OMPC_shared) {
734           DVar.RefExpr = nullptr;
735           DVar.CKind = OMPC_firstprivate;
736           return DVar;
737         }
738       } while (I != E && !isParallelOrTaskRegion(I->Directive));
739       DVar.CKind =
740           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
741       return DVar;
742     }
743   }
744   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
745   // in a Construct, implicitly determined, p.3]
746   //  For constructs other than task, if no default clause is present, these
747   //  variables inherit their data-sharing attributes from the enclosing
748   //  context.
749   return getDSA(++Iter, D);
750 }
751 
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)752 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
753                                          const Expr *NewDE) {
754   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
755   D = getCanonicalDecl(D);
756   SharingMapTy &StackElem = Stack.back().first.back();
757   auto It = StackElem.AlignedMap.find(D);
758   if (It == StackElem.AlignedMap.end()) {
759     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
760     StackElem.AlignedMap[D] = NewDE;
761     return nullptr;
762   }
763   assert(It->second && "Unexpected nullptr expr in the aligned map");
764   return It->second;
765 }
766 
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)767 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
768   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
769   D = getCanonicalDecl(D);
770   SharingMapTy &StackElem = Stack.back().first.back();
771   StackElem.LCVMap.try_emplace(
772       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
773 }
774 
775 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const776 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
777   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
778   D = getCanonicalDecl(D);
779   const SharingMapTy &StackElem = Stack.back().first.back();
780   auto It = StackElem.LCVMap.find(D);
781   if (It != StackElem.LCVMap.end())
782     return It->second;
783   return {0, nullptr};
784 }
785 
786 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const787 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
788   assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
789          "Data-sharing attributes stack is empty");
790   D = getCanonicalDecl(D);
791   const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
792   auto It = StackElem.LCVMap.find(D);
793   if (It != StackElem.LCVMap.end())
794     return It->second;
795   return {0, nullptr};
796 }
797 
getParentLoopControlVariable(unsigned I) const798 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
799   assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
800          "Data-sharing attributes stack is empty");
801   const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
802   if (StackElem.LCVMap.size() < I)
803     return nullptr;
804   for (const auto &Pair : StackElem.LCVMap)
805     if (Pair.second.first == I)
806       return Pair.first;
807   return nullptr;
808 }
809 
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy)810 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
811                         DeclRefExpr *PrivateCopy) {
812   D = getCanonicalDecl(D);
813   if (A == OMPC_threadprivate) {
814     DSAInfo &Data = Threadprivates[D];
815     Data.Attributes = A;
816     Data.RefExpr.setPointer(E);
817     Data.PrivateCopy = nullptr;
818   } else {
819     assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
820     DSAInfo &Data = Stack.back().first.back().SharingMap[D];
821     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
822            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
823            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
824            (isLoopControlVariable(D).first && A == OMPC_private));
825     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
826       Data.RefExpr.setInt(/*IntVal=*/true);
827       return;
828     }
829     const bool IsLastprivate =
830         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
831     Data.Attributes = A;
832     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
833     Data.PrivateCopy = PrivateCopy;
834     if (PrivateCopy) {
835       DSAInfo &Data =
836           Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
837       Data.Attributes = A;
838       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
839       Data.PrivateCopy = nullptr;
840     }
841   }
842 }
843 
844 /// 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)845 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
846                              StringRef Name, const AttrVec *Attrs = nullptr,
847                              DeclRefExpr *OrigRef = nullptr) {
848   DeclContext *DC = SemaRef.CurContext;
849   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
850   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
851   auto *Decl =
852       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
853   if (Attrs) {
854     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
855          I != E; ++I)
856       Decl->addAttr(*I);
857   }
858   Decl->setImplicit();
859   if (OrigRef) {
860     Decl->addAttr(
861         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
862   }
863   return Decl;
864 }
865 
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)866 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
867                                      SourceLocation Loc,
868                                      bool RefersToCapture = false) {
869   D->setReferenced();
870   D->markUsed(S.Context);
871   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
872                              SourceLocation(), D, RefersToCapture, Loc, Ty,
873                              VK_LValue);
874 }
875 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)876 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
877                                            BinaryOperatorKind BOK) {
878   D = getCanonicalDecl(D);
879   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
880   assert(
881       Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
882       "Additional reduction info may be specified only for reduction items.");
883   ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
884   assert(ReductionData.ReductionRange.isInvalid() &&
885          Stack.back().first.back().Directive == OMPD_taskgroup &&
886          "Additional reduction info may be specified only once for reduction "
887          "items.");
888   ReductionData.set(BOK, SR);
889   Expr *&TaskgroupReductionRef =
890       Stack.back().first.back().TaskgroupReductionRef;
891   if (!TaskgroupReductionRef) {
892     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
893                                SemaRef.Context.VoidPtrTy, ".task_red.");
894     TaskgroupReductionRef =
895         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
896   }
897 }
898 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)899 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
900                                            const Expr *ReductionRef) {
901   D = getCanonicalDecl(D);
902   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
903   assert(
904       Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
905       "Additional reduction info may be specified only for reduction items.");
906   ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
907   assert(ReductionData.ReductionRange.isInvalid() &&
908          Stack.back().first.back().Directive == OMPD_taskgroup &&
909          "Additional reduction info may be specified only once for reduction "
910          "items.");
911   ReductionData.set(ReductionRef, SR);
912   Expr *&TaskgroupReductionRef =
913       Stack.back().first.back().TaskgroupReductionRef;
914   if (!TaskgroupReductionRef) {
915     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
916                                SemaRef.Context.VoidPtrTy, ".task_red.");
917     TaskgroupReductionRef =
918         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
919   }
920 }
921 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const922 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
923     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
924     Expr *&TaskgroupDescriptor) const {
925   D = getCanonicalDecl(D);
926   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
927   if (Stack.back().first.empty())
928       return DSAVarData();
929   for (iterator I = std::next(Stack.back().first.rbegin(), 1),
930                 E = Stack.back().first.rend();
931        I != E; std::advance(I, 1)) {
932     const DSAInfo &Data = I->SharingMap.lookup(D);
933     if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
934       continue;
935     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
936     if (!ReductionData.ReductionOp ||
937         ReductionData.ReductionOp.is<const Expr *>())
938       return DSAVarData();
939     SR = ReductionData.ReductionRange;
940     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
941     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
942                                        "expression for the descriptor is not "
943                                        "set.");
944     TaskgroupDescriptor = I->TaskgroupReductionRef;
945     return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
946                       Data.PrivateCopy, I->DefaultAttrLoc);
947   }
948   return DSAVarData();
949 }
950 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const951 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
952     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
953     Expr *&TaskgroupDescriptor) const {
954   D = getCanonicalDecl(D);
955   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
956   if (Stack.back().first.empty())
957       return DSAVarData();
958   for (iterator I = std::next(Stack.back().first.rbegin(), 1),
959                 E = Stack.back().first.rend();
960        I != E; std::advance(I, 1)) {
961     const DSAInfo &Data = I->SharingMap.lookup(D);
962     if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
963       continue;
964     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
965     if (!ReductionData.ReductionOp ||
966         !ReductionData.ReductionOp.is<const Expr *>())
967       return DSAVarData();
968     SR = ReductionData.ReductionRange;
969     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
970     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
971                                        "expression for the descriptor is not "
972                                        "set.");
973     TaskgroupDescriptor = I->TaskgroupReductionRef;
974     return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
975                       Data.PrivateCopy, I->DefaultAttrLoc);
976   }
977   return DSAVarData();
978 }
979 
isOpenMPLocal(VarDecl * D,iterator Iter) const980 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
981   D = D->getCanonicalDecl();
982   if (!isStackEmpty()) {
983     iterator I = Iter, E = Stack.back().first.rend();
984     Scope *TopScope = nullptr;
985     while (I != E && !isParallelOrTaskRegion(I->Directive) &&
986            !isOpenMPTargetExecutionDirective(I->Directive))
987       ++I;
988     if (I == E)
989       return false;
990     TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
991     Scope *CurScope = getCurScope();
992     while (CurScope != TopScope && !CurScope->isDeclScope(D))
993       CurScope = CurScope->getParent();
994     return CurScope != TopScope;
995   }
996   return false;
997 }
998 
getTopDSA(ValueDecl * D,bool FromParent)999 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1000                                                    bool FromParent) {
1001   D = getCanonicalDecl(D);
1002   DSAVarData DVar;
1003 
1004   auto *VD = dyn_cast<VarDecl>(D);
1005   auto TI = Threadprivates.find(D);
1006   if (TI != Threadprivates.end()) {
1007     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1008     DVar.CKind = OMPC_threadprivate;
1009     return DVar;
1010   }
1011   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1012     DVar.RefExpr = buildDeclRefExpr(
1013         SemaRef, VD, D->getType().getNonReferenceType(),
1014         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1015     DVar.CKind = OMPC_threadprivate;
1016     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1017     return DVar;
1018   }
1019   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1020   // in a Construct, C/C++, predetermined, p.1]
1021   //  Variables appearing in threadprivate directives are threadprivate.
1022   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1023        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1024          SemaRef.getLangOpts().OpenMPUseTLS &&
1025          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1026       (VD && VD->getStorageClass() == SC_Register &&
1027        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1028     DVar.RefExpr = buildDeclRefExpr(
1029         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1030     DVar.CKind = OMPC_threadprivate;
1031     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1032     return DVar;
1033   }
1034   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1035       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1036       !isLoopControlVariable(D).first) {
1037     iterator IterTarget =
1038         std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1039                      [](const SharingMapTy &Data) {
1040                        return isOpenMPTargetExecutionDirective(Data.Directive);
1041                      });
1042     if (IterTarget != Stack.back().first.rend()) {
1043       iterator ParentIterTarget = std::next(IterTarget, 1);
1044       for (iterator Iter = Stack.back().first.rbegin();
1045            Iter != ParentIterTarget; std::advance(Iter, 1)) {
1046         if (isOpenMPLocal(VD, Iter)) {
1047           DVar.RefExpr =
1048               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1049                                D->getLocation());
1050           DVar.CKind = OMPC_threadprivate;
1051           return DVar;
1052         }
1053       }
1054       if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1055         auto DSAIter = IterTarget->SharingMap.find(D);
1056         if (DSAIter != IterTarget->SharingMap.end() &&
1057             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1058           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1059           DVar.CKind = OMPC_threadprivate;
1060           return DVar;
1061         }
1062         iterator End = Stack.back().first.rend();
1063         if (!SemaRef.isOpenMPCapturedByRef(
1064                 D, std::distance(ParentIterTarget, End))) {
1065           DVar.RefExpr =
1066               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1067                                IterTarget->ConstructLoc);
1068           DVar.CKind = OMPC_threadprivate;
1069           return DVar;
1070         }
1071       }
1072     }
1073   }
1074 
1075   if (isStackEmpty())
1076     // Not in OpenMP execution region and top scope was already checked.
1077     return DVar;
1078 
1079   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1080   // in a Construct, C/C++, predetermined, p.4]
1081   //  Static data members are shared.
1082   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1083   // in a Construct, C/C++, predetermined, p.7]
1084   //  Variables with static storage duration that are declared in a scope
1085   //  inside the construct are shared.
1086   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1087   if (VD && VD->isStaticDataMember()) {
1088     DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1089     if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1090       return DVar;
1091 
1092     DVar.CKind = OMPC_shared;
1093     return DVar;
1094   }
1095 
1096   QualType Type = D->getType().getNonReferenceType().getCanonicalType();
1097   bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1098   Type = SemaRef.getASTContext().getBaseElementType(Type);
1099   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1100   // in a Construct, C/C++, predetermined, p.6]
1101   //  Variables with const qualified type having no mutable member are
1102   //  shared.
1103   const CXXRecordDecl *RD =
1104       SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1105   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1106     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1107       RD = CTD->getTemplatedDecl();
1108   if (IsConstant &&
1109       !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1110         RD->hasMutableFields())) {
1111     // Variables with const-qualified type having no mutable member may be
1112     // listed in a firstprivate clause, even if they are static data members.
1113     DSAVarData DVarTemp =
1114         hasDSA(D, [](OpenMPClauseKind C) { return C == OMPC_firstprivate; },
1115                MatchesAlways, FromParent);
1116     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1117       return DVarTemp;
1118 
1119     DVar.CKind = OMPC_shared;
1120     return DVar;
1121   }
1122 
1123   // Explicitly specified attributes and local variables with predetermined
1124   // attributes.
1125   iterator I = Stack.back().first.rbegin();
1126   iterator EndI = Stack.back().first.rend();
1127   if (FromParent && I != EndI)
1128     std::advance(I, 1);
1129   auto It = I->SharingMap.find(D);
1130   if (It != I->SharingMap.end()) {
1131     const DSAInfo &Data = It->getSecond();
1132     DVar.RefExpr = Data.RefExpr.getPointer();
1133     DVar.PrivateCopy = Data.PrivateCopy;
1134     DVar.CKind = Data.Attributes;
1135     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1136     DVar.DKind = I->Directive;
1137   }
1138 
1139   return DVar;
1140 }
1141 
getImplicitDSA(ValueDecl * D,bool FromParent) const1142 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1143                                                         bool FromParent) const {
1144   if (isStackEmpty()) {
1145     iterator I;
1146     return getDSA(I, D);
1147   }
1148   D = getCanonicalDecl(D);
1149   iterator StartI = Stack.back().first.rbegin();
1150   iterator EndI = Stack.back().first.rend();
1151   if (FromParent && StartI != EndI)
1152     std::advance(StartI, 1);
1153   return getDSA(StartI, D);
1154 }
1155 
1156 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1157 DSAStackTy::hasDSA(ValueDecl *D,
1158                    const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1159                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1160                    bool FromParent) const {
1161   if (isStackEmpty())
1162     return {};
1163   D = getCanonicalDecl(D);
1164   iterator I = Stack.back().first.rbegin();
1165   iterator EndI = Stack.back().first.rend();
1166   if (FromParent && I != EndI)
1167     std::advance(I, 1);
1168   for (; I != EndI; std::advance(I, 1)) {
1169     if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1170       continue;
1171     iterator NewI = I;
1172     DSAVarData DVar = getDSA(NewI, D);
1173     if (I == NewI && CPred(DVar.CKind))
1174       return DVar;
1175   }
1176   return {};
1177 }
1178 
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1179 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1180     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1181     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1182     bool FromParent) const {
1183   if (isStackEmpty())
1184     return {};
1185   D = getCanonicalDecl(D);
1186   iterator StartI = Stack.back().first.rbegin();
1187   iterator EndI = Stack.back().first.rend();
1188   if (FromParent && StartI != EndI)
1189     std::advance(StartI, 1);
1190   if (StartI == EndI || !DPred(StartI->Directive))
1191     return {};
1192   iterator NewI = StartI;
1193   DSAVarData DVar = getDSA(NewI, D);
1194   return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1195 }
1196 
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind)> CPred,unsigned Level,bool NotLastprivate) const1197 bool DSAStackTy::hasExplicitDSA(
1198     const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1199     unsigned Level, bool NotLastprivate) const {
1200   if (isStackEmpty())
1201     return false;
1202   D = getCanonicalDecl(D);
1203   auto StartI = Stack.back().first.begin();
1204   auto EndI = Stack.back().first.end();
1205   if (std::distance(StartI, EndI) <= (int)Level)
1206     return false;
1207   std::advance(StartI, Level);
1208   auto I = StartI->SharingMap.find(D);
1209   return (I != StartI->SharingMap.end()) &&
1210          I->getSecond().RefExpr.getPointer() &&
1211          CPred(I->getSecond().Attributes) &&
1212          (!NotLastprivate || !I->getSecond().RefExpr.getInt());
1213 }
1214 
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1215 bool DSAStackTy::hasExplicitDirective(
1216     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1217     unsigned Level) const {
1218   if (isStackEmpty())
1219     return false;
1220   auto StartI = Stack.back().first.begin();
1221   auto EndI = Stack.back().first.end();
1222   if (std::distance(StartI, EndI) <= (int)Level)
1223     return false;
1224   std::advance(StartI, Level);
1225   return DPred(StartI->Directive);
1226 }
1227 
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1228 bool DSAStackTy::hasDirective(
1229     const llvm::function_ref<bool(OpenMPDirectiveKind,
1230                                   const DeclarationNameInfo &, SourceLocation)>
1231         DPred,
1232     bool FromParent) const {
1233   // We look only in the enclosing region.
1234   if (isStackEmpty())
1235     return false;
1236   auto StartI = std::next(Stack.back().first.rbegin());
1237   auto EndI = Stack.back().first.rend();
1238   if (FromParent && StartI != EndI)
1239     StartI = std::next(StartI);
1240   for (auto I = StartI, EE = EndI; I != EE; ++I) {
1241     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1242       return true;
1243   }
1244   return false;
1245 }
1246 
InitDataSharingAttributesStack()1247 void Sema::InitDataSharingAttributesStack() {
1248   VarDataSharingAttributesStack = new DSAStackTy(*this);
1249 }
1250 
1251 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1252 
pushOpenMPFunctionRegion()1253 void Sema::pushOpenMPFunctionRegion() {
1254   DSAStack->pushFunction();
1255 }
1256 
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1257 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1258   DSAStack->popFunction(OldFSI);
1259 }
1260 
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level) const1261 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
1262   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1263 
1264   ASTContext &Ctx = getASTContext();
1265   bool IsByRef = true;
1266 
1267   // Find the directive that is associated with the provided scope.
1268   D = cast<ValueDecl>(D->getCanonicalDecl());
1269   QualType Ty = D->getType();
1270 
1271   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1272     // This table summarizes how a given variable should be passed to the device
1273     // given its type and the clauses where it appears. This table is based on
1274     // the description in OpenMP 4.5 [2.10.4, target Construct] and
1275     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1276     //
1277     // =========================================================================
1278     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
1279     // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
1280     // =========================================================================
1281     // | scl  |               |     |       |       -       |          | bycopy|
1282     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
1283     // | scl  |               |  x  |   -   |       -       |     -    | null  |
1284     // | scl  |       x       |     |       |       -       |          | byref |
1285     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
1286     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
1287     // | scl  |               |  -  |   -   |       -       |     x    | byref |
1288     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
1289     //
1290     // | agg  |      n.a.     |     |       |       -       |          | byref |
1291     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
1292     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
1293     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
1294     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
1295     //
1296     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
1297     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
1298     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
1299     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
1300     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
1301     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
1302     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
1303     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
1304     // =========================================================================
1305     // Legend:
1306     //  scl - scalar
1307     //  ptr - pointer
1308     //  agg - aggregate
1309     //  x - applies
1310     //  - - invalid in this combination
1311     //  [] - mapped with an array section
1312     //  byref - should be mapped by reference
1313     //  byval - should be mapped by value
1314     //  null - initialize a local variable to null on the device
1315     //
1316     // Observations:
1317     //  - All scalar declarations that show up in a map clause have to be passed
1318     //    by reference, because they may have been mapped in the enclosing data
1319     //    environment.
1320     //  - If the scalar value does not fit the size of uintptr, it has to be
1321     //    passed by reference, regardless the result in the table above.
1322     //  - For pointers mapped by value that have either an implicit map or an
1323     //    array section, the runtime library may pass the NULL value to the
1324     //    device instead of the value passed to it by the compiler.
1325 
1326     if (Ty->isReferenceType())
1327       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1328 
1329     // Locate map clauses and see if the variable being captured is referred to
1330     // in any of those clauses. Here we only care about variables, not fields,
1331     // because fields are part of aggregates.
1332     bool IsVariableUsedInMapClause = false;
1333     bool IsVariableAssociatedWithSection = false;
1334 
1335     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1336         D, Level,
1337         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1338             OMPClauseMappableExprCommon::MappableExprComponentListRef
1339                 MapExprComponents,
1340             OpenMPClauseKind WhereFoundClauseKind) {
1341           // Only the map clause information influences how a variable is
1342           // captured. E.g. is_device_ptr does not require changing the default
1343           // behavior.
1344           if (WhereFoundClauseKind != OMPC_map)
1345             return false;
1346 
1347           auto EI = MapExprComponents.rbegin();
1348           auto EE = MapExprComponents.rend();
1349 
1350           assert(EI != EE && "Invalid map expression!");
1351 
1352           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1353             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1354 
1355           ++EI;
1356           if (EI == EE)
1357             return false;
1358 
1359           if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1360               isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1361               isa<MemberExpr>(EI->getAssociatedExpression())) {
1362             IsVariableAssociatedWithSection = true;
1363             // There is nothing more we need to know about this variable.
1364             return true;
1365           }
1366 
1367           // Keep looking for more map info.
1368           return false;
1369         });
1370 
1371     if (IsVariableUsedInMapClause) {
1372       // If variable is identified in a map clause it is always captured by
1373       // reference except if it is a pointer that is dereferenced somehow.
1374       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1375     } else {
1376       // By default, all the data that has a scalar type is mapped by copy
1377       // (except for reduction variables).
1378       IsByRef =
1379           !Ty->isScalarType() ||
1380           DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1381           DSAStack->hasExplicitDSA(
1382               D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1383     }
1384   }
1385 
1386   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1387     IsByRef =
1388         !DSAStack->hasExplicitDSA(
1389             D,
1390             [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1391             Level, /*NotLastprivate=*/true) &&
1392         // If the variable is artificial and must be captured by value - try to
1393         // capture by value.
1394         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1395           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1396   }
1397 
1398   // When passing data by copy, we need to make sure it fits the uintptr size
1399   // and alignment, because the runtime library only deals with uintptr types.
1400   // If it does not fit the uintptr size, we need to pass the data by reference
1401   // instead.
1402   if (!IsByRef &&
1403       (Ctx.getTypeSizeInChars(Ty) >
1404            Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1405        Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1406     IsByRef = true;
1407   }
1408 
1409   return IsByRef;
1410 }
1411 
getOpenMPNestingLevel() const1412 unsigned Sema::getOpenMPNestingLevel() const {
1413   assert(getLangOpts().OpenMP);
1414   return DSAStack->getNestingLevel();
1415 }
1416 
isInOpenMPTargetExecutionDirective() const1417 bool Sema::isInOpenMPTargetExecutionDirective() const {
1418   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1419           !DSAStack->isClauseParsingMode()) ||
1420          DSAStack->hasDirective(
1421              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1422                 SourceLocation) -> bool {
1423                return isOpenMPTargetExecutionDirective(K);
1424              },
1425              false);
1426 }
1427 
isOpenMPCapturedDecl(ValueDecl * D) const1428 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) const {
1429   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1430   D = getCanonicalDecl(D);
1431 
1432   // If we are attempting to capture a global variable in a directive with
1433   // 'target' we return true so that this global is also mapped to the device.
1434   //
1435   auto *VD = dyn_cast<VarDecl>(D);
1436   if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective()) {
1437     // If the declaration is enclosed in a 'declare target' directive,
1438     // then it should not be captured.
1439     //
1440     if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1441       return nullptr;
1442     return VD;
1443   }
1444 
1445   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1446       (!DSAStack->isClauseParsingMode() ||
1447        DSAStack->getParentDirective() != OMPD_unknown)) {
1448     auto &&Info = DSAStack->isLoopControlVariable(D);
1449     if (Info.first ||
1450         (VD && VD->hasLocalStorage() &&
1451          isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1452         (VD && DSAStack->isForceVarCapturing()))
1453       return VD ? VD : Info.second;
1454     DSAStackTy::DSAVarData DVarPrivate =
1455         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1456     if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1457       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1458     DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1459                                    [](OpenMPDirectiveKind) { return true; },
1460                                    DSAStack->isClauseParsingMode());
1461     if (DVarPrivate.CKind != OMPC_unknown)
1462       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1463   }
1464   return nullptr;
1465 }
1466 
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const1467 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1468                                         unsigned Level) const {
1469   SmallVector<OpenMPDirectiveKind, 4> Regions;
1470   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1471   FunctionScopesIndex -= Regions.size();
1472 }
1473 
isOpenMPPrivateDecl(const ValueDecl * D,unsigned Level) const1474 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
1475   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1476   return DSAStack->hasExplicitDSA(
1477              D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
1478          (DSAStack->isClauseParsingMode() &&
1479           DSAStack->getClauseParsingMode() == OMPC_private) ||
1480          // Consider taskgroup reduction descriptor variable a private to avoid
1481          // possible capture in the region.
1482          (DSAStack->hasExplicitDirective(
1483               [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1484               Level) &&
1485           DSAStack->isTaskgroupReductionRef(D, Level));
1486 }
1487 
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)1488 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
1489                                 unsigned Level) {
1490   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1491   D = getCanonicalDecl(D);
1492   OpenMPClauseKind OMPC = OMPC_unknown;
1493   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1494     const unsigned NewLevel = I - 1;
1495     if (DSAStack->hasExplicitDSA(D,
1496                                  [&OMPC](const OpenMPClauseKind K) {
1497                                    if (isOpenMPPrivate(K)) {
1498                                      OMPC = K;
1499                                      return true;
1500                                    }
1501                                    return false;
1502                                  },
1503                                  NewLevel))
1504       break;
1505     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1506             D, NewLevel,
1507             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1508                OpenMPClauseKind) { return true; })) {
1509       OMPC = OMPC_map;
1510       break;
1511     }
1512     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1513                                        NewLevel)) {
1514       OMPC = OMPC_map;
1515       if (D->getType()->isScalarType() &&
1516           DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1517               DefaultMapAttributes::DMA_tofrom_scalar)
1518         OMPC = OMPC_firstprivate;
1519       break;
1520     }
1521   }
1522   if (OMPC != OMPC_unknown)
1523     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1524 }
1525 
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level) const1526 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
1527                                       unsigned Level) const {
1528   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1529   // Return true if the current level is no longer enclosed in a target region.
1530 
1531   const auto *VD = dyn_cast<VarDecl>(D);
1532   return VD && !VD->hasLocalStorage() &&
1533          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1534                                         Level);
1535 }
1536 
DestroyDataSharingAttributesStack()1537 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1538 
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)1539 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1540                                const DeclarationNameInfo &DirName,
1541                                Scope *CurScope, SourceLocation Loc) {
1542   DSAStack->push(DKind, DirName, CurScope, Loc);
1543   PushExpressionEvaluationContext(
1544       ExpressionEvaluationContext::PotentiallyEvaluated);
1545 }
1546 
StartOpenMPClause(OpenMPClauseKind K)1547 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1548   DSAStack->setClauseParsingMode(K);
1549 }
1550 
EndOpenMPClause()1551 void Sema::EndOpenMPClause() {
1552   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1553 }
1554 
EndOpenMPDSABlock(Stmt * CurDirective)1555 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1556   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1557   //  A variable of class type (or array thereof) that appears in a lastprivate
1558   //  clause requires an accessible, unambiguous default constructor for the
1559   //  class type, unless the list item is also specified in a firstprivate
1560   //  clause.
1561   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1562     for (OMPClause *C : D->clauses()) {
1563       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1564         SmallVector<Expr *, 8> PrivateCopies;
1565         for (Expr *DE : Clause->varlists()) {
1566           if (DE->isValueDependent() || DE->isTypeDependent()) {
1567             PrivateCopies.push_back(nullptr);
1568             continue;
1569           }
1570           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1571           auto *VD = cast<VarDecl>(DRE->getDecl());
1572           QualType Type = VD->getType().getNonReferenceType();
1573           const DSAStackTy::DSAVarData DVar =
1574               DSAStack->getTopDSA(VD, /*FromParent=*/false);
1575           if (DVar.CKind == OMPC_lastprivate) {
1576             // Generate helper private variable and initialize it with the
1577             // default value. The address of the original variable is replaced
1578             // by the address of the new private variable in CodeGen. This new
1579             // variable is not added to IdResolver, so the code in the OpenMP
1580             // region uses original variable for proper diagnostics.
1581             VarDecl *VDPrivate = buildVarDecl(
1582                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1583                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
1584             ActOnUninitializedDecl(VDPrivate);
1585             if (VDPrivate->isInvalidDecl())
1586               continue;
1587             PrivateCopies.push_back(buildDeclRefExpr(
1588                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1589           } else {
1590             // The variable is also a firstprivate, so initialization sequence
1591             // for private copy is generated already.
1592             PrivateCopies.push_back(nullptr);
1593           }
1594         }
1595         // Set initializers to private copies if no errors were found.
1596         if (PrivateCopies.size() == Clause->varlist_size())
1597           Clause->setPrivateCopies(PrivateCopies);
1598       }
1599     }
1600   }
1601 
1602   DSAStack->pop();
1603   DiscardCleanupsInEvaluationContext();
1604   PopExpressionEvaluationContext();
1605 }
1606 
1607 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1608                                      Expr *NumIterations, Sema &SemaRef,
1609                                      Scope *S, DSAStackTy *Stack);
1610 
1611 namespace {
1612 
1613 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
1614 private:
1615   Sema &SemaRef;
1616 
1617 public:
VarDeclFilterCCC(Sema & S)1618   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)1619   bool ValidateCandidate(const TypoCorrection &Candidate) override {
1620     NamedDecl *ND = Candidate.getCorrectionDecl();
1621     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1622       return VD->hasGlobalStorage() &&
1623              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1624                                    SemaRef.getCurScope());
1625     }
1626     return false;
1627   }
1628 };
1629 
1630 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
1631 private:
1632   Sema &SemaRef;
1633 
1634 public:
VarOrFuncDeclFilterCCC(Sema & S)1635   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)1636   bool ValidateCandidate(const TypoCorrection &Candidate) override {
1637     NamedDecl *ND = Candidate.getCorrectionDecl();
1638     if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1639       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1640                                    SemaRef.getCurScope());
1641     }
1642     return false;
1643   }
1644 };
1645 
1646 } // namespace
1647 
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)1648 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1649                                          CXXScopeSpec &ScopeSpec,
1650                                          const DeclarationNameInfo &Id) {
1651   LookupResult Lookup(*this, Id, LookupOrdinaryName);
1652   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1653 
1654   if (Lookup.isAmbiguous())
1655     return ExprError();
1656 
1657   VarDecl *VD;
1658   if (!Lookup.isSingleResult()) {
1659     if (TypoCorrection Corrected = CorrectTypo(
1660             Id, LookupOrdinaryName, CurScope, nullptr,
1661             llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1662       diagnoseTypo(Corrected,
1663                    PDiag(Lookup.empty()
1664                              ? diag::err_undeclared_var_use_suggest
1665                              : diag::err_omp_expected_var_arg_suggest)
1666                        << Id.getName());
1667       VD = Corrected.getCorrectionDeclAs<VarDecl>();
1668     } else {
1669       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1670                                        : diag::err_omp_expected_var_arg)
1671           << Id.getName();
1672       return ExprError();
1673     }
1674   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1675     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1676     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1677     return ExprError();
1678   }
1679   Lookup.suppressDiagnostics();
1680 
1681   // OpenMP [2.9.2, Syntax, C/C++]
1682   //   Variables must be file-scope, namespace-scope, or static block-scope.
1683   if (!VD->hasGlobalStorage()) {
1684     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1685         << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1686     bool IsDecl =
1687         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1688     Diag(VD->getLocation(),
1689          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1690         << VD;
1691     return ExprError();
1692   }
1693 
1694   VarDecl *CanonicalVD = VD->getCanonicalDecl();
1695   NamedDecl *ND = CanonicalVD;
1696   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1697   //   A threadprivate directive for file-scope variables must appear outside
1698   //   any definition or declaration.
1699   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1700       !getCurLexicalContext()->isTranslationUnit()) {
1701     Diag(Id.getLoc(), diag::err_omp_var_scope)
1702         << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1703     bool IsDecl =
1704         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1705     Diag(VD->getLocation(),
1706          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1707         << VD;
1708     return ExprError();
1709   }
1710   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1711   //   A threadprivate directive for static class member variables must appear
1712   //   in the class definition, in the same scope in which the member
1713   //   variables are declared.
1714   if (CanonicalVD->isStaticDataMember() &&
1715       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1716     Diag(Id.getLoc(), diag::err_omp_var_scope)
1717         << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1718     bool IsDecl =
1719         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1720     Diag(VD->getLocation(),
1721          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1722         << VD;
1723     return ExprError();
1724   }
1725   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1726   //   A threadprivate directive for namespace-scope variables must appear
1727   //   outside any definition or declaration other than the namespace
1728   //   definition itself.
1729   if (CanonicalVD->getDeclContext()->isNamespace() &&
1730       (!getCurLexicalContext()->isFileContext() ||
1731        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1732     Diag(Id.getLoc(), diag::err_omp_var_scope)
1733         << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1734     bool IsDecl =
1735         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1736     Diag(VD->getLocation(),
1737          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1738         << VD;
1739     return ExprError();
1740   }
1741   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1742   //   A threadprivate directive for static block-scope variables must appear
1743   //   in the scope of the variable and not in a nested scope.
1744   if (CanonicalVD->isStaticLocal() && CurScope &&
1745       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1746     Diag(Id.getLoc(), diag::err_omp_var_scope)
1747         << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1748     bool IsDecl =
1749         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1750     Diag(VD->getLocation(),
1751          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1752         << VD;
1753     return ExprError();
1754   }
1755 
1756   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1757   //   A threadprivate directive must lexically precede all references to any
1758   //   of the variables in its list.
1759   if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1760     Diag(Id.getLoc(), diag::err_omp_var_used)
1761         << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1762     return ExprError();
1763   }
1764 
1765   QualType ExprType = VD->getType().getNonReferenceType();
1766   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1767                              SourceLocation(), VD,
1768                              /*RefersToEnclosingVariableOrCapture=*/false,
1769                              Id.getLoc(), ExprType, VK_LValue);
1770 }
1771 
1772 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)1773 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1774                                         ArrayRef<Expr *> VarList) {
1775   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1776     CurContext->addDecl(D);
1777     return DeclGroupPtrTy::make(DeclGroupRef(D));
1778   }
1779   return nullptr;
1780 }
1781 
1782 namespace {
1783 class LocalVarRefChecker final
1784     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1785   Sema &SemaRef;
1786 
1787 public:
VisitDeclRefExpr(const DeclRefExpr * E)1788   bool VisitDeclRefExpr(const DeclRefExpr *E) {
1789     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1790       if (VD->hasLocalStorage()) {
1791         SemaRef.Diag(E->getLocStart(),
1792                      diag::err_omp_local_var_in_threadprivate_init)
1793             << E->getSourceRange();
1794         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1795             << VD << VD->getSourceRange();
1796         return true;
1797       }
1798     }
1799     return false;
1800   }
VisitStmt(const Stmt * S)1801   bool VisitStmt(const Stmt *S) {
1802     for (const Stmt *Child : S->children()) {
1803       if (Child && Visit(Child))
1804         return true;
1805     }
1806     return false;
1807   }
LocalVarRefChecker(Sema & SemaRef)1808   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1809 };
1810 } // namespace
1811 
1812 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)1813 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1814   SmallVector<Expr *, 8> Vars;
1815   for (Expr *RefExpr : VarList) {
1816     auto *DE = cast<DeclRefExpr>(RefExpr);
1817     auto *VD = cast<VarDecl>(DE->getDecl());
1818     SourceLocation ILoc = DE->getExprLoc();
1819 
1820     // Mark variable as used.
1821     VD->setReferenced();
1822     VD->markUsed(Context);
1823 
1824     QualType QType = VD->getType();
1825     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1826       // It will be analyzed later.
1827       Vars.push_back(DE);
1828       continue;
1829     }
1830 
1831     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1832     //   A threadprivate variable must not have an incomplete type.
1833     if (RequireCompleteType(ILoc, VD->getType(),
1834                             diag::err_omp_threadprivate_incomplete_type)) {
1835       continue;
1836     }
1837 
1838     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1839     //   A threadprivate variable must not have a reference type.
1840     if (VD->getType()->isReferenceType()) {
1841       Diag(ILoc, diag::err_omp_ref_type_arg)
1842           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1843       bool IsDecl =
1844           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1845       Diag(VD->getLocation(),
1846            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1847           << VD;
1848       continue;
1849     }
1850 
1851     // Check if this is a TLS variable. If TLS is not being supported, produce
1852     // the corresponding diagnostic.
1853     if ((VD->getTLSKind() != VarDecl::TLS_None &&
1854          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1855            getLangOpts().OpenMPUseTLS &&
1856            getASTContext().getTargetInfo().isTLSSupported())) ||
1857         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1858          !VD->isLocalVarDecl())) {
1859       Diag(ILoc, diag::err_omp_var_thread_local)
1860           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1861       bool IsDecl =
1862           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1863       Diag(VD->getLocation(),
1864            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1865           << VD;
1866       continue;
1867     }
1868 
1869     // Check if initial value of threadprivate variable reference variable with
1870     // local storage (it is not supported by runtime).
1871     if (const Expr *Init = VD->getAnyInitializer()) {
1872       LocalVarRefChecker Checker(*this);
1873       if (Checker.Visit(Init))
1874         continue;
1875     }
1876 
1877     Vars.push_back(RefExpr);
1878     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1879     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1880         Context, SourceRange(Loc, Loc)));
1881     if (ASTMutationListener *ML = Context.getASTMutationListener())
1882       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1883   }
1884   OMPThreadPrivateDecl *D = nullptr;
1885   if (!Vars.empty()) {
1886     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1887                                      Vars);
1888     D->setAccess(AS_public);
1889   }
1890   return D;
1891 }
1892 
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar=false)1893 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
1894                               const ValueDecl *D,
1895                               const DSAStackTy::DSAVarData &DVar,
1896                               bool IsLoopIterVar = false) {
1897   if (DVar.RefExpr) {
1898     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1899         << getOpenMPClauseName(DVar.CKind);
1900     return;
1901   }
1902   enum {
1903     PDSA_StaticMemberShared,
1904     PDSA_StaticLocalVarShared,
1905     PDSA_LoopIterVarPrivate,
1906     PDSA_LoopIterVarLinear,
1907     PDSA_LoopIterVarLastprivate,
1908     PDSA_ConstVarShared,
1909     PDSA_GlobalVarShared,
1910     PDSA_TaskVarFirstprivate,
1911     PDSA_LocalVarPrivate,
1912     PDSA_Implicit
1913   } Reason = PDSA_Implicit;
1914   bool ReportHint = false;
1915   auto ReportLoc = D->getLocation();
1916   auto *VD = dyn_cast<VarDecl>(D);
1917   if (IsLoopIterVar) {
1918     if (DVar.CKind == OMPC_private)
1919       Reason = PDSA_LoopIterVarPrivate;
1920     else if (DVar.CKind == OMPC_lastprivate)
1921       Reason = PDSA_LoopIterVarLastprivate;
1922     else
1923       Reason = PDSA_LoopIterVarLinear;
1924   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1925              DVar.CKind == OMPC_firstprivate) {
1926     Reason = PDSA_TaskVarFirstprivate;
1927     ReportLoc = DVar.ImplicitDSALoc;
1928   } else if (VD && VD->isStaticLocal())
1929     Reason = PDSA_StaticLocalVarShared;
1930   else if (VD && VD->isStaticDataMember())
1931     Reason = PDSA_StaticMemberShared;
1932   else if (VD && VD->isFileVarDecl())
1933     Reason = PDSA_GlobalVarShared;
1934   else if (D->getType().isConstant(SemaRef.getASTContext()))
1935     Reason = PDSA_ConstVarShared;
1936   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1937     ReportHint = true;
1938     Reason = PDSA_LocalVarPrivate;
1939   }
1940   if (Reason != PDSA_Implicit) {
1941     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1942         << Reason << ReportHint
1943         << getOpenMPDirectiveName(Stack->getCurrentDirective());
1944   } else if (DVar.ImplicitDSALoc.isValid()) {
1945     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1946         << getOpenMPClauseName(DVar.CKind);
1947   }
1948 }
1949 
1950 namespace {
1951 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
1952   DSAStackTy *Stack;
1953   Sema &SemaRef;
1954   bool ErrorFound = false;
1955   CapturedStmt *CS = nullptr;
1956   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
1957   llvm::SmallVector<Expr *, 4> ImplicitMap;
1958   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
1959   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
1960 
1961 public:
VisitDeclRefExpr(DeclRefExpr * E)1962   void VisitDeclRefExpr(DeclRefExpr *E) {
1963     if (E->isTypeDependent() || E->isValueDependent() ||
1964         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1965       return;
1966     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1967       VD = VD->getCanonicalDecl();
1968       // Skip internally declared variables.
1969       if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1970         return;
1971 
1972       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
1973       // Check if the variable has explicit DSA set and stop analysis if it so.
1974       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1975         return;
1976 
1977       // Skip internally declared static variables.
1978       llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
1979           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
1980       if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
1981           (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
1982         return;
1983 
1984       SourceLocation ELoc = E->getExprLoc();
1985       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1986       // The default(none) clause requires that each variable that is referenced
1987       // in the construct, and does not have a predetermined data-sharing
1988       // attribute, must have its data-sharing attribute explicitly determined
1989       // by being listed in a data-sharing attribute clause.
1990       if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1991           isParallelOrTaskRegion(DKind) &&
1992           VarsWithInheritedDSA.count(VD) == 0) {
1993         VarsWithInheritedDSA[VD] = E;
1994         return;
1995       }
1996 
1997       if (isOpenMPTargetExecutionDirective(DKind) &&
1998           !Stack->isLoopControlVariable(VD).first) {
1999         if (!Stack->checkMappableExprComponentListsForDecl(
2000                 VD, /*CurrentRegionOnly=*/true,
2001                 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2002                        StackComponents,
2003                    OpenMPClauseKind) {
2004                   // Variable is used if it has been marked as an array, array
2005                   // section or the variable iself.
2006                   return StackComponents.size() == 1 ||
2007                          std::all_of(
2008                              std::next(StackComponents.rbegin()),
2009                              StackComponents.rend(),
2010                              [](const OMPClauseMappableExprCommon::
2011                                     MappableComponent &MC) {
2012                                return MC.getAssociatedDeclaration() ==
2013                                           nullptr &&
2014                                       (isa<OMPArraySectionExpr>(
2015                                            MC.getAssociatedExpression()) ||
2016                                        isa<ArraySubscriptExpr>(
2017                                            MC.getAssociatedExpression()));
2018                              });
2019                 })) {
2020           bool IsFirstprivate = false;
2021           // By default lambdas are captured as firstprivates.
2022           if (const auto *RD =
2023                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2024             IsFirstprivate = RD->isLambda();
2025           IsFirstprivate =
2026               IsFirstprivate ||
2027               (VD->getType().getNonReferenceType()->isScalarType() &&
2028                Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2029           if (IsFirstprivate)
2030             ImplicitFirstprivate.emplace_back(E);
2031           else
2032             ImplicitMap.emplace_back(E);
2033           return;
2034         }
2035       }
2036 
2037       // OpenMP [2.9.3.6, Restrictions, p.2]
2038       //  A list item that appears in a reduction clause of the innermost
2039       //  enclosing worksharing or parallel construct may not be accessed in an
2040       //  explicit task.
2041       DVar = Stack->hasInnermostDSA(
2042           VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2043           [](OpenMPDirectiveKind K) {
2044             return isOpenMPParallelDirective(K) ||
2045                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2046           },
2047           /*FromParent=*/true);
2048       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2049         ErrorFound = true;
2050         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2051         reportOriginalDsa(SemaRef, Stack, VD, DVar);
2052         return;
2053       }
2054 
2055       // Define implicit data-sharing attributes for task.
2056       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2057       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2058           !Stack->isLoopControlVariable(VD).first)
2059         ImplicitFirstprivate.push_back(E);
2060     }
2061   }
VisitMemberExpr(MemberExpr * E)2062   void VisitMemberExpr(MemberExpr *E) {
2063     if (E->isTypeDependent() || E->isValueDependent() ||
2064         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2065       return;
2066     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2067     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2068     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2069       if (!FD)
2070         return;
2071       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2072       // Check if the variable has explicit DSA set and stop analysis if it
2073       // so.
2074       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2075         return;
2076 
2077       if (isOpenMPTargetExecutionDirective(DKind) &&
2078           !Stack->isLoopControlVariable(FD).first &&
2079           !Stack->checkMappableExprComponentListsForDecl(
2080               FD, /*CurrentRegionOnly=*/true,
2081               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2082                      StackComponents,
2083                  OpenMPClauseKind) {
2084                 return isa<CXXThisExpr>(
2085                     cast<MemberExpr>(
2086                         StackComponents.back().getAssociatedExpression())
2087                         ->getBase()
2088                         ->IgnoreParens());
2089               })) {
2090         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2091         //  A bit-field cannot appear in a map clause.
2092         //
2093         if (FD->isBitField())
2094           return;
2095         ImplicitMap.emplace_back(E);
2096         return;
2097       }
2098 
2099       SourceLocation ELoc = E->getExprLoc();
2100       // OpenMP [2.9.3.6, Restrictions, p.2]
2101       //  A list item that appears in a reduction clause of the innermost
2102       //  enclosing worksharing or parallel construct may not be accessed in
2103       //  an  explicit task.
2104       DVar = Stack->hasInnermostDSA(
2105           FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2106           [](OpenMPDirectiveKind K) {
2107             return isOpenMPParallelDirective(K) ||
2108                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2109           },
2110           /*FromParent=*/true);
2111       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2112         ErrorFound = true;
2113         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2114         reportOriginalDsa(SemaRef, Stack, FD, DVar);
2115         return;
2116       }
2117 
2118       // Define implicit data-sharing attributes for task.
2119       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2120       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2121           !Stack->isLoopControlVariable(FD).first)
2122         ImplicitFirstprivate.push_back(E);
2123       return;
2124     }
2125     if (isOpenMPTargetExecutionDirective(DKind)) {
2126       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2127       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2128                                         /*NoDiagnose=*/true))
2129         return;
2130       const auto *VD = cast<ValueDecl>(
2131           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2132       if (!Stack->checkMappableExprComponentListsForDecl(
2133               VD, /*CurrentRegionOnly=*/true,
2134               [&CurComponents](
2135                   OMPClauseMappableExprCommon::MappableExprComponentListRef
2136                       StackComponents,
2137                   OpenMPClauseKind) {
2138                 auto CCI = CurComponents.rbegin();
2139                 auto CCE = CurComponents.rend();
2140                 for (const auto &SC : llvm::reverse(StackComponents)) {
2141                   // Do both expressions have the same kind?
2142                   if (CCI->getAssociatedExpression()->getStmtClass() !=
2143                       SC.getAssociatedExpression()->getStmtClass())
2144                     if (!(isa<OMPArraySectionExpr>(
2145                               SC.getAssociatedExpression()) &&
2146                           isa<ArraySubscriptExpr>(
2147                               CCI->getAssociatedExpression())))
2148                       return false;
2149 
2150                   const Decl *CCD = CCI->getAssociatedDeclaration();
2151                   const Decl *SCD = SC.getAssociatedDeclaration();
2152                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2153                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2154                   if (SCD != CCD)
2155                     return false;
2156                   std::advance(CCI, 1);
2157                   if (CCI == CCE)
2158                     break;
2159                 }
2160                 return true;
2161               })) {
2162         Visit(E->getBase());
2163       }
2164     } else {
2165       Visit(E->getBase());
2166     }
2167   }
VisitOMPExecutableDirective(OMPExecutableDirective * S)2168   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2169     for (OMPClause *C : S->clauses()) {
2170       // Skip analysis of arguments of implicitly defined firstprivate clause
2171       // for task|target directives.
2172       // Skip analysis of arguments of implicitly defined map clause for target
2173       // directives.
2174       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2175                  C->isImplicit())) {
2176         for (Stmt *CC : C->children()) {
2177           if (CC)
2178             Visit(CC);
2179         }
2180       }
2181     }
2182   }
VisitStmt(Stmt * S)2183   void VisitStmt(Stmt *S) {
2184     for (Stmt *C : S->children()) {
2185       if (C && !isa<OMPExecutableDirective>(C))
2186         Visit(C);
2187     }
2188   }
2189 
isErrorFound() const2190   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const2191   ArrayRef<Expr *> getImplicitFirstprivate() const {
2192     return ImplicitFirstprivate;
2193   }
getImplicitMap() const2194   ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
getVarsWithInheritedDSA() const2195   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
2196     return VarsWithInheritedDSA;
2197   }
2198 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)2199   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2200       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2201 };
2202 } // namespace
2203 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)2204 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2205   switch (DKind) {
2206   case OMPD_parallel:
2207   case OMPD_parallel_for:
2208   case OMPD_parallel_for_simd:
2209   case OMPD_parallel_sections:
2210   case OMPD_teams:
2211   case OMPD_teams_distribute:
2212   case OMPD_teams_distribute_simd: {
2213     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2214     QualType KmpInt32PtrTy =
2215         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2216     Sema::CapturedParamNameType Params[] = {
2217         std::make_pair(".global_tid.", KmpInt32PtrTy),
2218         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2219         std::make_pair(StringRef(), QualType()) // __context with shared vars
2220     };
2221     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2222                              Params);
2223     break;
2224   }
2225   case OMPD_target_teams:
2226   case OMPD_target_parallel:
2227   case OMPD_target_parallel_for:
2228   case OMPD_target_parallel_for_simd:
2229   case OMPD_target_teams_distribute:
2230   case OMPD_target_teams_distribute_simd: {
2231     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2232     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2233     QualType KmpInt32PtrTy =
2234         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2235     QualType Args[] = {VoidPtrTy};
2236     FunctionProtoType::ExtProtoInfo EPI;
2237     EPI.Variadic = true;
2238     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2239     Sema::CapturedParamNameType Params[] = {
2240         std::make_pair(".global_tid.", KmpInt32Ty),
2241         std::make_pair(".part_id.", KmpInt32PtrTy),
2242         std::make_pair(".privates.", VoidPtrTy),
2243         std::make_pair(
2244             ".copy_fn.",
2245             Context.getPointerType(CopyFnType).withConst().withRestrict()),
2246         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2247         std::make_pair(StringRef(), QualType()) // __context with shared vars
2248     };
2249     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2250                              Params);
2251     // Mark this captured region as inlined, because we don't use outlined
2252     // function directly.
2253     getCurCapturedRegion()->TheCapturedDecl->addAttr(
2254         AlwaysInlineAttr::CreateImplicit(
2255             Context, AlwaysInlineAttr::Keyword_forceinline));
2256     Sema::CapturedParamNameType ParamsTarget[] = {
2257         std::make_pair(StringRef(), QualType()) // __context with shared vars
2258     };
2259     // Start a captured region for 'target' with no implicit parameters.
2260     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2261                              ParamsTarget);
2262     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2263         std::make_pair(".global_tid.", KmpInt32PtrTy),
2264         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2265         std::make_pair(StringRef(), QualType()) // __context with shared vars
2266     };
2267     // Start a captured region for 'teams' or 'parallel'.  Both regions have
2268     // the same implicit parameters.
2269     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2270                              ParamsTeamsOrParallel);
2271     break;
2272   }
2273   case OMPD_target:
2274   case OMPD_target_simd: {
2275     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2276     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2277     QualType KmpInt32PtrTy =
2278         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2279     QualType Args[] = {VoidPtrTy};
2280     FunctionProtoType::ExtProtoInfo EPI;
2281     EPI.Variadic = true;
2282     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2283     Sema::CapturedParamNameType Params[] = {
2284         std::make_pair(".global_tid.", KmpInt32Ty),
2285         std::make_pair(".part_id.", KmpInt32PtrTy),
2286         std::make_pair(".privates.", VoidPtrTy),
2287         std::make_pair(
2288             ".copy_fn.",
2289             Context.getPointerType(CopyFnType).withConst().withRestrict()),
2290         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2291         std::make_pair(StringRef(), QualType()) // __context with shared vars
2292     };
2293     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2294                              Params);
2295     // Mark this captured region as inlined, because we don't use outlined
2296     // function directly.
2297     getCurCapturedRegion()->TheCapturedDecl->addAttr(
2298         AlwaysInlineAttr::CreateImplicit(
2299             Context, AlwaysInlineAttr::Keyword_forceinline));
2300     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2301                              std::make_pair(StringRef(), QualType()));
2302     break;
2303   }
2304   case OMPD_simd:
2305   case OMPD_for:
2306   case OMPD_for_simd:
2307   case OMPD_sections:
2308   case OMPD_section:
2309   case OMPD_single:
2310   case OMPD_master:
2311   case OMPD_critical:
2312   case OMPD_taskgroup:
2313   case OMPD_distribute:
2314   case OMPD_distribute_simd:
2315   case OMPD_ordered:
2316   case OMPD_atomic:
2317   case OMPD_target_data: {
2318     Sema::CapturedParamNameType Params[] = {
2319         std::make_pair(StringRef(), QualType()) // __context with shared vars
2320     };
2321     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2322                              Params);
2323     break;
2324   }
2325   case OMPD_task: {
2326     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2327     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2328     QualType KmpInt32PtrTy =
2329         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2330     QualType Args[] = {VoidPtrTy};
2331     FunctionProtoType::ExtProtoInfo EPI;
2332     EPI.Variadic = true;
2333     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2334     Sema::CapturedParamNameType Params[] = {
2335         std::make_pair(".global_tid.", KmpInt32Ty),
2336         std::make_pair(".part_id.", KmpInt32PtrTy),
2337         std::make_pair(".privates.", VoidPtrTy),
2338         std::make_pair(
2339             ".copy_fn.",
2340             Context.getPointerType(CopyFnType).withConst().withRestrict()),
2341         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2342         std::make_pair(StringRef(), QualType()) // __context with shared vars
2343     };
2344     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2345                              Params);
2346     // Mark this captured region as inlined, because we don't use outlined
2347     // function directly.
2348     getCurCapturedRegion()->TheCapturedDecl->addAttr(
2349         AlwaysInlineAttr::CreateImplicit(
2350             Context, AlwaysInlineAttr::Keyword_forceinline));
2351     break;
2352   }
2353   case OMPD_taskloop:
2354   case OMPD_taskloop_simd: {
2355     QualType KmpInt32Ty =
2356         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
2357             .withConst();
2358     QualType KmpUInt64Ty =
2359         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
2360             .withConst();
2361     QualType KmpInt64Ty =
2362         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
2363             .withConst();
2364     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2365     QualType KmpInt32PtrTy =
2366         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2367     QualType Args[] = {VoidPtrTy};
2368     FunctionProtoType::ExtProtoInfo EPI;
2369     EPI.Variadic = true;
2370     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2371     Sema::CapturedParamNameType Params[] = {
2372         std::make_pair(".global_tid.", KmpInt32Ty),
2373         std::make_pair(".part_id.", KmpInt32PtrTy),
2374         std::make_pair(".privates.", VoidPtrTy),
2375         std::make_pair(
2376             ".copy_fn.",
2377             Context.getPointerType(CopyFnType).withConst().withRestrict()),
2378         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2379         std::make_pair(".lb.", KmpUInt64Ty),
2380         std::make_pair(".ub.", KmpUInt64Ty),
2381         std::make_pair(".st.", KmpInt64Ty),
2382         std::make_pair(".liter.", KmpInt32Ty),
2383         std::make_pair(".reductions.", VoidPtrTy),
2384         std::make_pair(StringRef(), QualType()) // __context with shared vars
2385     };
2386     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2387                              Params);
2388     // Mark this captured region as inlined, because we don't use outlined
2389     // function directly.
2390     getCurCapturedRegion()->TheCapturedDecl->addAttr(
2391         AlwaysInlineAttr::CreateImplicit(
2392             Context, AlwaysInlineAttr::Keyword_forceinline));
2393     break;
2394   }
2395   case OMPD_distribute_parallel_for_simd:
2396   case OMPD_distribute_parallel_for: {
2397     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2398     QualType KmpInt32PtrTy =
2399         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2400     Sema::CapturedParamNameType Params[] = {
2401         std::make_pair(".global_tid.", KmpInt32PtrTy),
2402         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2403         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2404         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2405         std::make_pair(StringRef(), QualType()) // __context with shared vars
2406     };
2407     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2408                              Params);
2409     break;
2410   }
2411   case OMPD_target_teams_distribute_parallel_for:
2412   case OMPD_target_teams_distribute_parallel_for_simd: {
2413     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2414     QualType KmpInt32PtrTy =
2415         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2416     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2417 
2418     QualType Args[] = {VoidPtrTy};
2419     FunctionProtoType::ExtProtoInfo EPI;
2420     EPI.Variadic = true;
2421     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2422     Sema::CapturedParamNameType Params[] = {
2423         std::make_pair(".global_tid.", KmpInt32Ty),
2424         std::make_pair(".part_id.", KmpInt32PtrTy),
2425         std::make_pair(".privates.", VoidPtrTy),
2426         std::make_pair(
2427             ".copy_fn.",
2428             Context.getPointerType(CopyFnType).withConst().withRestrict()),
2429         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2430         std::make_pair(StringRef(), QualType()) // __context with shared vars
2431     };
2432     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2433                              Params);
2434     // Mark this captured region as inlined, because we don't use outlined
2435     // function directly.
2436     getCurCapturedRegion()->TheCapturedDecl->addAttr(
2437         AlwaysInlineAttr::CreateImplicit(
2438             Context, AlwaysInlineAttr::Keyword_forceinline));
2439     Sema::CapturedParamNameType ParamsTarget[] = {
2440         std::make_pair(StringRef(), QualType()) // __context with shared vars
2441     };
2442     // Start a captured region for 'target' with no implicit parameters.
2443     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2444                              ParamsTarget);
2445 
2446     Sema::CapturedParamNameType ParamsTeams[] = {
2447         std::make_pair(".global_tid.", KmpInt32PtrTy),
2448         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2449         std::make_pair(StringRef(), QualType()) // __context with shared vars
2450     };
2451     // Start a captured region for 'target' with no implicit parameters.
2452     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2453                              ParamsTeams);
2454 
2455     Sema::CapturedParamNameType ParamsParallel[] = {
2456         std::make_pair(".global_tid.", KmpInt32PtrTy),
2457         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2458         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2459         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2460         std::make_pair(StringRef(), QualType()) // __context with shared vars
2461     };
2462     // Start a captured region for 'teams' or 'parallel'.  Both regions have
2463     // the same implicit parameters.
2464     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2465                              ParamsParallel);
2466     break;
2467   }
2468 
2469   case OMPD_teams_distribute_parallel_for:
2470   case OMPD_teams_distribute_parallel_for_simd: {
2471     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2472     QualType KmpInt32PtrTy =
2473         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2474 
2475     Sema::CapturedParamNameType ParamsTeams[] = {
2476         std::make_pair(".global_tid.", KmpInt32PtrTy),
2477         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2478         std::make_pair(StringRef(), QualType()) // __context with shared vars
2479     };
2480     // Start a captured region for 'target' with no implicit parameters.
2481     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2482                              ParamsTeams);
2483 
2484     Sema::CapturedParamNameType ParamsParallel[] = {
2485         std::make_pair(".global_tid.", KmpInt32PtrTy),
2486         std::make_pair(".bound_tid.", KmpInt32PtrTy),
2487         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2488         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2489         std::make_pair(StringRef(), QualType()) // __context with shared vars
2490     };
2491     // Start a captured region for 'teams' or 'parallel'.  Both regions have
2492     // the same implicit parameters.
2493     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2494                              ParamsParallel);
2495     break;
2496   }
2497   case OMPD_target_update:
2498   case OMPD_target_enter_data:
2499   case OMPD_target_exit_data: {
2500     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2501     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2502     QualType KmpInt32PtrTy =
2503         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2504     QualType Args[] = {VoidPtrTy};
2505     FunctionProtoType::ExtProtoInfo EPI;
2506     EPI.Variadic = true;
2507     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2508     Sema::CapturedParamNameType Params[] = {
2509         std::make_pair(".global_tid.", KmpInt32Ty),
2510         std::make_pair(".part_id.", KmpInt32PtrTy),
2511         std::make_pair(".privates.", VoidPtrTy),
2512         std::make_pair(
2513             ".copy_fn.",
2514             Context.getPointerType(CopyFnType).withConst().withRestrict()),
2515         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2516         std::make_pair(StringRef(), QualType()) // __context with shared vars
2517     };
2518     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2519                              Params);
2520     // Mark this captured region as inlined, because we don't use outlined
2521     // function directly.
2522     getCurCapturedRegion()->TheCapturedDecl->addAttr(
2523         AlwaysInlineAttr::CreateImplicit(
2524             Context, AlwaysInlineAttr::Keyword_forceinline));
2525     break;
2526   }
2527   case OMPD_threadprivate:
2528   case OMPD_taskyield:
2529   case OMPD_barrier:
2530   case OMPD_taskwait:
2531   case OMPD_cancellation_point:
2532   case OMPD_cancel:
2533   case OMPD_flush:
2534   case OMPD_declare_reduction:
2535   case OMPD_declare_simd:
2536   case OMPD_declare_target:
2537   case OMPD_end_declare_target:
2538     llvm_unreachable("OpenMP Directive is not allowed");
2539   case OMPD_unknown:
2540     llvm_unreachable("Unknown OpenMP directive");
2541   }
2542 }
2543 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)2544 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2545   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2546   getOpenMPCaptureRegions(CaptureRegions, DKind);
2547   return CaptureRegions.size();
2548 }
2549 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)2550 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2551                                              Expr *CaptureExpr, bool WithInit,
2552                                              bool AsExpression) {
2553   assert(CaptureExpr);
2554   ASTContext &C = S.getASTContext();
2555   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2556   QualType Ty = Init->getType();
2557   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2558     if (S.getLangOpts().CPlusPlus) {
2559       Ty = C.getLValueReferenceType(Ty);
2560     } else {
2561       Ty = C.getPointerType(Ty);
2562       ExprResult Res =
2563           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2564       if (!Res.isUsable())
2565         return nullptr;
2566       Init = Res.get();
2567     }
2568     WithInit = true;
2569   }
2570   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2571                                           CaptureExpr->getLocStart());
2572   if (!WithInit)
2573     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2574   S.CurContext->addHiddenDecl(CED);
2575   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2576   return CED;
2577 }
2578 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)2579 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2580                                  bool WithInit) {
2581   OMPCapturedExprDecl *CD;
2582   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
2583     CD = cast<OMPCapturedExprDecl>(VD);
2584   else
2585     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2586                           /*AsExpression=*/false);
2587   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2588                           CaptureExpr->getExprLoc());
2589 }
2590 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)2591 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2592   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2593   if (!Ref) {
2594     OMPCapturedExprDecl *CD = buildCaptureDecl(
2595         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2596         /*WithInit=*/true, /*AsExpression=*/true);
2597     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2598                            CaptureExpr->getExprLoc());
2599   }
2600   ExprResult Res = Ref;
2601   if (!S.getLangOpts().CPlusPlus &&
2602       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2603       Ref->getType()->isPointerType()) {
2604     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2605     if (!Res.isUsable())
2606       return ExprError();
2607   }
2608   return S.DefaultLvalueConversion(Res.get());
2609 }
2610 
2611 namespace {
2612 // OpenMP directives parsed in this section are represented as a
2613 // CapturedStatement with an associated statement.  If a syntax error
2614 // is detected during the parsing of the associated statement, the
2615 // compiler must abort processing and close the CapturedStatement.
2616 //
2617 // Combined directives such as 'target parallel' have more than one
2618 // nested CapturedStatements.  This RAII ensures that we unwind out
2619 // of all the nested CapturedStatements when an error is found.
2620 class CaptureRegionUnwinderRAII {
2621 private:
2622   Sema &S;
2623   bool &ErrorFound;
2624   OpenMPDirectiveKind DKind = OMPD_unknown;
2625 
2626 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)2627   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2628                             OpenMPDirectiveKind DKind)
2629       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()2630   ~CaptureRegionUnwinderRAII() {
2631     if (ErrorFound) {
2632       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2633       while (--ThisCaptureLevel >= 0)
2634         S.ActOnCapturedRegionError();
2635     }
2636   }
2637 };
2638 } // namespace
2639 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)2640 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2641                                       ArrayRef<OMPClause *> Clauses) {
2642   bool ErrorFound = false;
2643   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2644       *this, ErrorFound, DSAStack->getCurrentDirective());
2645   if (!S.isUsable()) {
2646     ErrorFound = true;
2647     return StmtError();
2648   }
2649 
2650   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2651   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2652   OMPOrderedClause *OC = nullptr;
2653   OMPScheduleClause *SC = nullptr;
2654   SmallVector<const OMPLinearClause *, 4> LCs;
2655   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
2656   // This is required for proper codegen.
2657   for (OMPClause *Clause : Clauses) {
2658     if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2659         Clause->getClauseKind() == OMPC_in_reduction) {
2660       // Capture taskgroup task_reduction descriptors inside the tasking regions
2661       // with the corresponding in_reduction items.
2662       auto *IRC = cast<OMPInReductionClause>(Clause);
2663       for (Expr *E : IRC->taskgroup_descriptors())
2664         if (E)
2665           MarkDeclarationsReferencedInExpr(E);
2666     }
2667     if (isOpenMPPrivate(Clause->getClauseKind()) ||
2668         Clause->getClauseKind() == OMPC_copyprivate ||
2669         (getLangOpts().OpenMPUseTLS &&
2670          getASTContext().getTargetInfo().isTLSSupported() &&
2671          Clause->getClauseKind() == OMPC_copyin)) {
2672       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2673       // Mark all variables in private list clauses as used in inner region.
2674       for (Stmt *VarRef : Clause->children()) {
2675         if (auto *E = cast_or_null<Expr>(VarRef)) {
2676           MarkDeclarationsReferencedInExpr(E);
2677         }
2678       }
2679       DSAStack->setForceVarCapturing(/*V=*/false);
2680     } else if (CaptureRegions.size() > 1 ||
2681                CaptureRegions.back() != OMPD_unknown) {
2682       if (auto *C = OMPClauseWithPreInit::get(Clause))
2683         PICs.push_back(C);
2684       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2685         if (Expr *E = C->getPostUpdateExpr())
2686           MarkDeclarationsReferencedInExpr(E);
2687       }
2688     }
2689     if (Clause->getClauseKind() == OMPC_schedule)
2690       SC = cast<OMPScheduleClause>(Clause);
2691     else if (Clause->getClauseKind() == OMPC_ordered)
2692       OC = cast<OMPOrderedClause>(Clause);
2693     else if (Clause->getClauseKind() == OMPC_linear)
2694       LCs.push_back(cast<OMPLinearClause>(Clause));
2695   }
2696   // OpenMP, 2.7.1 Loop Construct, Restrictions
2697   // The nonmonotonic modifier cannot be specified if an ordered clause is
2698   // specified.
2699   if (SC &&
2700       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2701        SC->getSecondScheduleModifier() ==
2702            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2703       OC) {
2704     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2705              ? SC->getFirstScheduleModifierLoc()
2706              : SC->getSecondScheduleModifierLoc(),
2707          diag::err_omp_schedule_nonmonotonic_ordered)
2708         << SourceRange(OC->getLocStart(), OC->getLocEnd());
2709     ErrorFound = true;
2710   }
2711   if (!LCs.empty() && OC && OC->getNumForLoops()) {
2712     for (const OMPLinearClause *C : LCs) {
2713       Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2714           << SourceRange(OC->getLocStart(), OC->getLocEnd());
2715     }
2716     ErrorFound = true;
2717   }
2718   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2719       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2720       OC->getNumForLoops()) {
2721     Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2722         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
2723     ErrorFound = true;
2724   }
2725   if (ErrorFound) {
2726     return StmtError();
2727   }
2728   StmtResult SR = S;
2729   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2730     // Mark all variables in private list clauses as used in inner region.
2731     // Required for proper codegen of combined directives.
2732     // TODO: add processing for other clauses.
2733     if (ThisCaptureRegion != OMPD_unknown) {
2734       for (const clang::OMPClauseWithPreInit *C : PICs) {
2735         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2736         // Find the particular capture region for the clause if the
2737         // directive is a combined one with multiple capture regions.
2738         // If the directive is not a combined one, the capture region
2739         // associated with the clause is OMPD_unknown and is generated
2740         // only once.
2741         if (CaptureRegion == ThisCaptureRegion ||
2742             CaptureRegion == OMPD_unknown) {
2743           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2744             for (Decl *D : DS->decls())
2745               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2746           }
2747         }
2748       }
2749     }
2750     SR = ActOnCapturedRegionEnd(SR.get());
2751   }
2752   return SR;
2753 }
2754 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)2755 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2756                               OpenMPDirectiveKind CancelRegion,
2757                               SourceLocation StartLoc) {
2758   // CancelRegion is only needed for cancel and cancellation_point.
2759   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2760     return false;
2761 
2762   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2763       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2764     return false;
2765 
2766   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2767       << getOpenMPDirectiveName(CancelRegion);
2768   return true;
2769 }
2770 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)2771 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
2772                                   OpenMPDirectiveKind CurrentRegion,
2773                                   const DeclarationNameInfo &CurrentName,
2774                                   OpenMPDirectiveKind CancelRegion,
2775                                   SourceLocation StartLoc) {
2776   if (Stack->getCurScope()) {
2777     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
2778     OpenMPDirectiveKind OffendingRegion = ParentRegion;
2779     bool NestingProhibited = false;
2780     bool CloseNesting = true;
2781     bool OrphanSeen = false;
2782     enum {
2783       NoRecommend,
2784       ShouldBeInParallelRegion,
2785       ShouldBeInOrderedRegion,
2786       ShouldBeInTargetRegion,
2787       ShouldBeInTeamsRegion
2788     } Recommend = NoRecommend;
2789     if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2790       // OpenMP [2.16, Nesting of Regions]
2791       // OpenMP constructs may not be nested inside a simd region.
2792       // OpenMP [2.8.1,simd Construct, Restrictions]
2793       // An ordered construct with the simd clause is the only OpenMP
2794       // construct that can appear in the simd region.
2795       // Allowing a SIMD construct nested in another SIMD construct is an
2796       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2797       // message.
2798       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2799                                  ? diag::err_omp_prohibited_region_simd
2800                                  : diag::warn_omp_nesting_simd);
2801       return CurrentRegion != OMPD_simd;
2802     }
2803     if (ParentRegion == OMPD_atomic) {
2804       // OpenMP [2.16, Nesting of Regions]
2805       // OpenMP constructs may not be nested inside an atomic region.
2806       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2807       return true;
2808     }
2809     if (CurrentRegion == OMPD_section) {
2810       // OpenMP [2.7.2, sections Construct, Restrictions]
2811       // Orphaned section directives are prohibited. That is, the section
2812       // directives must appear within the sections construct and must not be
2813       // encountered elsewhere in the sections region.
2814       if (ParentRegion != OMPD_sections &&
2815           ParentRegion != OMPD_parallel_sections) {
2816         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2817             << (ParentRegion != OMPD_unknown)
2818             << getOpenMPDirectiveName(ParentRegion);
2819         return true;
2820       }
2821       return false;
2822     }
2823     // Allow some constructs (except teams) to be orphaned (they could be
2824     // used in functions, called from OpenMP regions with the required
2825     // preconditions).
2826     if (ParentRegion == OMPD_unknown &&
2827         !isOpenMPNestingTeamsDirective(CurrentRegion))
2828       return false;
2829     if (CurrentRegion == OMPD_cancellation_point ||
2830         CurrentRegion == OMPD_cancel) {
2831       // OpenMP [2.16, Nesting of Regions]
2832       // A cancellation point construct for which construct-type-clause is
2833       // taskgroup must be nested inside a task construct. A cancellation
2834       // point construct for which construct-type-clause is not taskgroup must
2835       // be closely nested inside an OpenMP construct that matches the type
2836       // specified in construct-type-clause.
2837       // A cancel construct for which construct-type-clause is taskgroup must be
2838       // nested inside a task construct. A cancel construct for which
2839       // construct-type-clause is not taskgroup must be closely nested inside an
2840       // OpenMP construct that matches the type specified in
2841       // construct-type-clause.
2842       NestingProhibited =
2843           !((CancelRegion == OMPD_parallel &&
2844              (ParentRegion == OMPD_parallel ||
2845               ParentRegion == OMPD_target_parallel)) ||
2846             (CancelRegion == OMPD_for &&
2847              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2848               ParentRegion == OMPD_target_parallel_for ||
2849               ParentRegion == OMPD_distribute_parallel_for ||
2850               ParentRegion == OMPD_teams_distribute_parallel_for ||
2851               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2852             (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2853             (CancelRegion == OMPD_sections &&
2854              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2855               ParentRegion == OMPD_parallel_sections)));
2856     } else if (CurrentRegion == OMPD_master) {
2857       // OpenMP [2.16, Nesting of Regions]
2858       // A master region may not be closely nested inside a worksharing,
2859       // atomic, or explicit task region.
2860       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2861                           isOpenMPTaskingDirective(ParentRegion);
2862     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2863       // OpenMP [2.16, Nesting of Regions]
2864       // A critical region may not be nested (closely or otherwise) inside a
2865       // critical region with the same name. Note that this restriction is not
2866       // sufficient to prevent deadlock.
2867       SourceLocation PreviousCriticalLoc;
2868       bool DeadLock = Stack->hasDirective(
2869           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2870                                               const DeclarationNameInfo &DNI,
2871                                               SourceLocation Loc) {
2872             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2873               PreviousCriticalLoc = Loc;
2874               return true;
2875             }
2876             return false;
2877           },
2878           false /* skip top directive */);
2879       if (DeadLock) {
2880         SemaRef.Diag(StartLoc,
2881                      diag::err_omp_prohibited_region_critical_same_name)
2882             << CurrentName.getName();
2883         if (PreviousCriticalLoc.isValid())
2884           SemaRef.Diag(PreviousCriticalLoc,
2885                        diag::note_omp_previous_critical_region);
2886         return true;
2887       }
2888     } else if (CurrentRegion == OMPD_barrier) {
2889       // OpenMP [2.16, Nesting of Regions]
2890       // A barrier region may not be closely nested inside a worksharing,
2891       // explicit task, critical, ordered, atomic, or master region.
2892       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2893                           isOpenMPTaskingDirective(ParentRegion) ||
2894                           ParentRegion == OMPD_master ||
2895                           ParentRegion == OMPD_critical ||
2896                           ParentRegion == OMPD_ordered;
2897     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2898                !isOpenMPParallelDirective(CurrentRegion) &&
2899                !isOpenMPTeamsDirective(CurrentRegion)) {
2900       // OpenMP [2.16, Nesting of Regions]
2901       // A worksharing region may not be closely nested inside a worksharing,
2902       // explicit task, critical, ordered, atomic, or master region.
2903       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2904                           isOpenMPTaskingDirective(ParentRegion) ||
2905                           ParentRegion == OMPD_master ||
2906                           ParentRegion == OMPD_critical ||
2907                           ParentRegion == OMPD_ordered;
2908       Recommend = ShouldBeInParallelRegion;
2909     } else if (CurrentRegion == OMPD_ordered) {
2910       // OpenMP [2.16, Nesting of Regions]
2911       // An ordered region may not be closely nested inside a critical,
2912       // atomic, or explicit task region.
2913       // An ordered region must be closely nested inside a loop region (or
2914       // parallel loop region) with an ordered clause.
2915       // OpenMP [2.8.1,simd Construct, Restrictions]
2916       // An ordered construct with the simd clause is the only OpenMP construct
2917       // that can appear in the simd region.
2918       NestingProhibited = ParentRegion == OMPD_critical ||
2919                           isOpenMPTaskingDirective(ParentRegion) ||
2920                           !(isOpenMPSimdDirective(ParentRegion) ||
2921                             Stack->isParentOrderedRegion());
2922       Recommend = ShouldBeInOrderedRegion;
2923     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2924       // OpenMP [2.16, Nesting of Regions]
2925       // If specified, a teams construct must be contained within a target
2926       // construct.
2927       NestingProhibited = ParentRegion != OMPD_target;
2928       OrphanSeen = ParentRegion == OMPD_unknown;
2929       Recommend = ShouldBeInTargetRegion;
2930     }
2931     if (!NestingProhibited &&
2932         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2933         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2934         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2935       // OpenMP [2.16, Nesting of Regions]
2936       // distribute, parallel, parallel sections, parallel workshare, and the
2937       // parallel loop and parallel loop SIMD constructs are the only OpenMP
2938       // constructs that can be closely nested in the teams region.
2939       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2940                           !isOpenMPDistributeDirective(CurrentRegion);
2941       Recommend = ShouldBeInParallelRegion;
2942     }
2943     if (!NestingProhibited &&
2944         isOpenMPNestingDistributeDirective(CurrentRegion)) {
2945       // OpenMP 4.5 [2.17 Nesting of Regions]
2946       // The region associated with the distribute construct must be strictly
2947       // nested inside a teams region
2948       NestingProhibited =
2949           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2950       Recommend = ShouldBeInTeamsRegion;
2951     }
2952     if (!NestingProhibited &&
2953         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2954          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2955       // OpenMP 4.5 [2.17 Nesting of Regions]
2956       // If a target, target update, target data, target enter data, or
2957       // target exit data construct is encountered during execution of a
2958       // target region, the behavior is unspecified.
2959       NestingProhibited = Stack->hasDirective(
2960           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2961                              SourceLocation) {
2962             if (isOpenMPTargetExecutionDirective(K)) {
2963               OffendingRegion = K;
2964               return true;
2965             }
2966             return false;
2967           },
2968           false /* don't skip top directive */);
2969       CloseNesting = false;
2970     }
2971     if (NestingProhibited) {
2972       if (OrphanSeen) {
2973         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2974             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2975       } else {
2976         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2977             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2978             << Recommend << getOpenMPDirectiveName(CurrentRegion);
2979       }
2980       return true;
2981     }
2982   }
2983   return false;
2984 }
2985 
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)2986 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
2987                            ArrayRef<OMPClause *> Clauses,
2988                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2989   bool ErrorFound = false;
2990   unsigned NamedModifiersNumber = 0;
2991   SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
2992       OMPD_unknown + 1);
2993   SmallVector<SourceLocation, 4> NameModifierLoc;
2994   for (const OMPClause *C : Clauses) {
2995     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2996       // At most one if clause without a directive-name-modifier can appear on
2997       // the directive.
2998       OpenMPDirectiveKind CurNM = IC->getNameModifier();
2999       if (FoundNameModifiers[CurNM]) {
3000         S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
3001             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3002             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3003         ErrorFound = true;
3004       } else if (CurNM != OMPD_unknown) {
3005         NameModifierLoc.push_back(IC->getNameModifierLoc());
3006         ++NamedModifiersNumber;
3007       }
3008       FoundNameModifiers[CurNM] = IC;
3009       if (CurNM == OMPD_unknown)
3010         continue;
3011       // Check if the specified name modifier is allowed for the current
3012       // directive.
3013       // At most one if clause with the particular directive-name-modifier can
3014       // appear on the directive.
3015       bool MatchFound = false;
3016       for (auto NM : AllowedNameModifiers) {
3017         if (CurNM == NM) {
3018           MatchFound = true;
3019           break;
3020         }
3021       }
3022       if (!MatchFound) {
3023         S.Diag(IC->getNameModifierLoc(),
3024                diag::err_omp_wrong_if_directive_name_modifier)
3025             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
3026         ErrorFound = true;
3027       }
3028     }
3029   }
3030   // If any if clause on the directive includes a directive-name-modifier then
3031   // all if clauses on the directive must include a directive-name-modifier.
3032   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3033     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3034       S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
3035              diag::err_omp_no_more_if_clause);
3036     } else {
3037       std::string Values;
3038       std::string Sep(", ");
3039       unsigned AllowedCnt = 0;
3040       unsigned TotalAllowedNum =
3041           AllowedNameModifiers.size() - NamedModifiersNumber;
3042       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3043            ++Cnt) {
3044         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3045         if (!FoundNameModifiers[NM]) {
3046           Values += "'";
3047           Values += getOpenMPDirectiveName(NM);
3048           Values += "'";
3049           if (AllowedCnt + 2 == TotalAllowedNum)
3050             Values += " or ";
3051           else if (AllowedCnt + 1 != TotalAllowedNum)
3052             Values += Sep;
3053           ++AllowedCnt;
3054         }
3055       }
3056       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
3057              diag::err_omp_unnamed_if_clause)
3058           << (TotalAllowedNum > 1) << Values;
3059     }
3060     for (SourceLocation Loc : NameModifierLoc) {
3061       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3062     }
3063     ErrorFound = true;
3064   }
3065   return ErrorFound;
3066 }
3067 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)3068 StmtResult Sema::ActOnOpenMPExecutableDirective(
3069     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
3070     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3071     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
3072   StmtResult Res = StmtError();
3073   // First check CancelRegion which is then used in checkNestingOfRegions.
3074   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
3075       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
3076                             StartLoc))
3077     return StmtError();
3078 
3079   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
3080   VarsWithInheritedDSAType VarsWithInheritedDSA;
3081   bool ErrorFound = false;
3082   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3083   if (AStmt && !CurContext->isDependentContext()) {
3084     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3085 
3086     // Check default data sharing attributes for referenced variables.
3087     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
3088     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3089     Stmt *S = AStmt;
3090     while (--ThisCaptureLevel >= 0)
3091       S = cast<CapturedStmt>(S)->getCapturedStmt();
3092     DSAChecker.Visit(S);
3093     if (DSAChecker.isErrorFound())
3094       return StmtError();
3095     // Generate list of implicitly defined firstprivate variables.
3096     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3097 
3098     SmallVector<Expr *, 4> ImplicitFirstprivates(
3099         DSAChecker.getImplicitFirstprivate().begin(),
3100         DSAChecker.getImplicitFirstprivate().end());
3101     SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3102                                         DSAChecker.getImplicitMap().end());
3103     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
3104     for (OMPClause *C : Clauses) {
3105       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
3106         for (Expr *E : IRC->taskgroup_descriptors())
3107           if (E)
3108             ImplicitFirstprivates.emplace_back(E);
3109       }
3110     }
3111     if (!ImplicitFirstprivates.empty()) {
3112       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3113               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3114               SourceLocation())) {
3115         ClausesWithImplicit.push_back(Implicit);
3116         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3117                      ImplicitFirstprivates.size();
3118       } else {
3119         ErrorFound = true;
3120       }
3121     }
3122     if (!ImplicitMaps.empty()) {
3123       if (OMPClause *Implicit = ActOnOpenMPMapClause(
3124               OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
3125               SourceLocation(), SourceLocation(), ImplicitMaps,
3126               SourceLocation(), SourceLocation(), SourceLocation())) {
3127         ClausesWithImplicit.emplace_back(Implicit);
3128         ErrorFound |=
3129             cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3130       } else {
3131         ErrorFound = true;
3132       }
3133     }
3134   }
3135 
3136   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3137   switch (Kind) {
3138   case OMPD_parallel:
3139     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3140                                        EndLoc);
3141     AllowedNameModifiers.push_back(OMPD_parallel);
3142     break;
3143   case OMPD_simd:
3144     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3145                                    VarsWithInheritedDSA);
3146     break;
3147   case OMPD_for:
3148     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3149                                   VarsWithInheritedDSA);
3150     break;
3151   case OMPD_for_simd:
3152     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3153                                       EndLoc, VarsWithInheritedDSA);
3154     break;
3155   case OMPD_sections:
3156     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3157                                        EndLoc);
3158     break;
3159   case OMPD_section:
3160     assert(ClausesWithImplicit.empty() &&
3161            "No clauses are allowed for 'omp section' directive");
3162     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3163     break;
3164   case OMPD_single:
3165     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3166                                      EndLoc);
3167     break;
3168   case OMPD_master:
3169     assert(ClausesWithImplicit.empty() &&
3170            "No clauses are allowed for 'omp master' directive");
3171     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3172     break;
3173   case OMPD_critical:
3174     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3175                                        StartLoc, EndLoc);
3176     break;
3177   case OMPD_parallel_for:
3178     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3179                                           EndLoc, VarsWithInheritedDSA);
3180     AllowedNameModifiers.push_back(OMPD_parallel);
3181     break;
3182   case OMPD_parallel_for_simd:
3183     Res = ActOnOpenMPParallelForSimdDirective(
3184         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3185     AllowedNameModifiers.push_back(OMPD_parallel);
3186     break;
3187   case OMPD_parallel_sections:
3188     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3189                                                StartLoc, EndLoc);
3190     AllowedNameModifiers.push_back(OMPD_parallel);
3191     break;
3192   case OMPD_task:
3193     Res =
3194         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3195     AllowedNameModifiers.push_back(OMPD_task);
3196     break;
3197   case OMPD_taskyield:
3198     assert(ClausesWithImplicit.empty() &&
3199            "No clauses are allowed for 'omp taskyield' directive");
3200     assert(AStmt == nullptr &&
3201            "No associated statement allowed for 'omp taskyield' directive");
3202     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3203     break;
3204   case OMPD_barrier:
3205     assert(ClausesWithImplicit.empty() &&
3206            "No clauses are allowed for 'omp barrier' directive");
3207     assert(AStmt == nullptr &&
3208            "No associated statement allowed for 'omp barrier' directive");
3209     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3210     break;
3211   case OMPD_taskwait:
3212     assert(ClausesWithImplicit.empty() &&
3213            "No clauses are allowed for 'omp taskwait' directive");
3214     assert(AStmt == nullptr &&
3215            "No associated statement allowed for 'omp taskwait' directive");
3216     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3217     break;
3218   case OMPD_taskgroup:
3219     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3220                                         EndLoc);
3221     break;
3222   case OMPD_flush:
3223     assert(AStmt == nullptr &&
3224            "No associated statement allowed for 'omp flush' directive");
3225     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3226     break;
3227   case OMPD_ordered:
3228     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3229                                       EndLoc);
3230     break;
3231   case OMPD_atomic:
3232     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3233                                      EndLoc);
3234     break;
3235   case OMPD_teams:
3236     Res =
3237         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3238     break;
3239   case OMPD_target:
3240     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3241                                      EndLoc);
3242     AllowedNameModifiers.push_back(OMPD_target);
3243     break;
3244   case OMPD_target_parallel:
3245     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3246                                              StartLoc, EndLoc);
3247     AllowedNameModifiers.push_back(OMPD_target);
3248     AllowedNameModifiers.push_back(OMPD_parallel);
3249     break;
3250   case OMPD_target_parallel_for:
3251     Res = ActOnOpenMPTargetParallelForDirective(
3252         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3253     AllowedNameModifiers.push_back(OMPD_target);
3254     AllowedNameModifiers.push_back(OMPD_parallel);
3255     break;
3256   case OMPD_cancellation_point:
3257     assert(ClausesWithImplicit.empty() &&
3258            "No clauses are allowed for 'omp cancellation point' directive");
3259     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3260                                "cancellation point' directive");
3261     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3262     break;
3263   case OMPD_cancel:
3264     assert(AStmt == nullptr &&
3265            "No associated statement allowed for 'omp cancel' directive");
3266     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3267                                      CancelRegion);
3268     AllowedNameModifiers.push_back(OMPD_cancel);
3269     break;
3270   case OMPD_target_data:
3271     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3272                                          EndLoc);
3273     AllowedNameModifiers.push_back(OMPD_target_data);
3274     break;
3275   case OMPD_target_enter_data:
3276     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3277                                               EndLoc, AStmt);
3278     AllowedNameModifiers.push_back(OMPD_target_enter_data);
3279     break;
3280   case OMPD_target_exit_data:
3281     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3282                                              EndLoc, AStmt);
3283     AllowedNameModifiers.push_back(OMPD_target_exit_data);
3284     break;
3285   case OMPD_taskloop:
3286     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3287                                        EndLoc, VarsWithInheritedDSA);
3288     AllowedNameModifiers.push_back(OMPD_taskloop);
3289     break;
3290   case OMPD_taskloop_simd:
3291     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3292                                            EndLoc, VarsWithInheritedDSA);
3293     AllowedNameModifiers.push_back(OMPD_taskloop);
3294     break;
3295   case OMPD_distribute:
3296     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3297                                          EndLoc, VarsWithInheritedDSA);
3298     break;
3299   case OMPD_target_update:
3300     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3301                                            EndLoc, AStmt);
3302     AllowedNameModifiers.push_back(OMPD_target_update);
3303     break;
3304   case OMPD_distribute_parallel_for:
3305     Res = ActOnOpenMPDistributeParallelForDirective(
3306         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3307     AllowedNameModifiers.push_back(OMPD_parallel);
3308     break;
3309   case OMPD_distribute_parallel_for_simd:
3310     Res = ActOnOpenMPDistributeParallelForSimdDirective(
3311         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3312     AllowedNameModifiers.push_back(OMPD_parallel);
3313     break;
3314   case OMPD_distribute_simd:
3315     Res = ActOnOpenMPDistributeSimdDirective(
3316         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3317     break;
3318   case OMPD_target_parallel_for_simd:
3319     Res = ActOnOpenMPTargetParallelForSimdDirective(
3320         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3321     AllowedNameModifiers.push_back(OMPD_target);
3322     AllowedNameModifiers.push_back(OMPD_parallel);
3323     break;
3324   case OMPD_target_simd:
3325     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3326                                          EndLoc, VarsWithInheritedDSA);
3327     AllowedNameModifiers.push_back(OMPD_target);
3328     break;
3329   case OMPD_teams_distribute:
3330     Res = ActOnOpenMPTeamsDistributeDirective(
3331         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3332     break;
3333   case OMPD_teams_distribute_simd:
3334     Res = ActOnOpenMPTeamsDistributeSimdDirective(
3335         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3336     break;
3337   case OMPD_teams_distribute_parallel_for_simd:
3338     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3339         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3340     AllowedNameModifiers.push_back(OMPD_parallel);
3341     break;
3342   case OMPD_teams_distribute_parallel_for:
3343     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3344         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3345     AllowedNameModifiers.push_back(OMPD_parallel);
3346     break;
3347   case OMPD_target_teams:
3348     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3349                                           EndLoc);
3350     AllowedNameModifiers.push_back(OMPD_target);
3351     break;
3352   case OMPD_target_teams_distribute:
3353     Res = ActOnOpenMPTargetTeamsDistributeDirective(
3354         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3355     AllowedNameModifiers.push_back(OMPD_target);
3356     break;
3357   case OMPD_target_teams_distribute_parallel_for:
3358     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3359         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3360     AllowedNameModifiers.push_back(OMPD_target);
3361     AllowedNameModifiers.push_back(OMPD_parallel);
3362     break;
3363   case OMPD_target_teams_distribute_parallel_for_simd:
3364     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3365         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3366     AllowedNameModifiers.push_back(OMPD_target);
3367     AllowedNameModifiers.push_back(OMPD_parallel);
3368     break;
3369   case OMPD_target_teams_distribute_simd:
3370     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3371         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3372     AllowedNameModifiers.push_back(OMPD_target);
3373     break;
3374   case OMPD_declare_target:
3375   case OMPD_end_declare_target:
3376   case OMPD_threadprivate:
3377   case OMPD_declare_reduction:
3378   case OMPD_declare_simd:
3379     llvm_unreachable("OpenMP Directive is not allowed");
3380   case OMPD_unknown:
3381     llvm_unreachable("Unknown OpenMP directive");
3382   }
3383 
3384   for (const auto &P : VarsWithInheritedDSA) {
3385     Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3386         << P.first << P.second->getSourceRange();
3387   }
3388   ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3389 
3390   if (!AllowedNameModifiers.empty())
3391     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3392                  ErrorFound;
3393 
3394   if (ErrorFound)
3395     return StmtError();
3396   return Res;
3397 }
3398 
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)3399 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3400     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3401     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3402     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3403     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3404   assert(Aligneds.size() == Alignments.size());
3405   assert(Linears.size() == LinModifiers.size());
3406   assert(Linears.size() == Steps.size());
3407   if (!DG || DG.get().isNull())
3408     return DeclGroupPtrTy();
3409 
3410   if (!DG.get().isSingleDecl()) {
3411     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3412     return DG;
3413   }
3414   Decl *ADecl = DG.get().getSingleDecl();
3415   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3416     ADecl = FTD->getTemplatedDecl();
3417 
3418   auto *FD = dyn_cast<FunctionDecl>(ADecl);
3419   if (!FD) {
3420     Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3421     return DeclGroupPtrTy();
3422   }
3423 
3424   // OpenMP [2.8.2, declare simd construct, Description]
3425   // The parameter of the simdlen clause must be a constant positive integer
3426   // expression.
3427   ExprResult SL;
3428   if (Simdlen)
3429     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3430   // OpenMP [2.8.2, declare simd construct, Description]
3431   // The special this pointer can be used as if was one of the arguments to the
3432   // function in any of the linear, aligned, or uniform clauses.
3433   // The uniform clause declares one or more arguments to have an invariant
3434   // value for all concurrent invocations of the function in the execution of a
3435   // single SIMD loop.
3436   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3437   const Expr *UniformedLinearThis = nullptr;
3438   for (const Expr *E : Uniforms) {
3439     E = E->IgnoreParenImpCasts();
3440     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3441       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3442         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3443             FD->getParamDecl(PVD->getFunctionScopeIndex())
3444                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3445           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3446           continue;
3447         }
3448     if (isa<CXXThisExpr>(E)) {
3449       UniformedLinearThis = E;
3450       continue;
3451     }
3452     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3453         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3454   }
3455   // OpenMP [2.8.2, declare simd construct, Description]
3456   // The aligned clause declares that the object to which each list item points
3457   // is aligned to the number of bytes expressed in the optional parameter of
3458   // the aligned clause.
3459   // The special this pointer can be used as if was one of the arguments to the
3460   // function in any of the linear, aligned, or uniform clauses.
3461   // The type of list items appearing in the aligned clause must be array,
3462   // pointer, reference to array, or reference to pointer.
3463   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3464   const Expr *AlignedThis = nullptr;
3465   for (const Expr *E : Aligneds) {
3466     E = E->IgnoreParenImpCasts();
3467     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3468       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3469         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3470         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3471             FD->getParamDecl(PVD->getFunctionScopeIndex())
3472                     ->getCanonicalDecl() == CanonPVD) {
3473           // OpenMP  [2.8.1, simd construct, Restrictions]
3474           // A list-item cannot appear in more than one aligned clause.
3475           if (AlignedArgs.count(CanonPVD) > 0) {
3476             Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3477                 << 1 << E->getSourceRange();
3478             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3479                  diag::note_omp_explicit_dsa)
3480                 << getOpenMPClauseName(OMPC_aligned);
3481             continue;
3482           }
3483           AlignedArgs[CanonPVD] = E;
3484           QualType QTy = PVD->getType()
3485                              .getNonReferenceType()
3486                              .getUnqualifiedType()
3487                              .getCanonicalType();
3488           const Type *Ty = QTy.getTypePtrOrNull();
3489           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3490             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3491                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3492             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3493           }
3494           continue;
3495         }
3496       }
3497     if (isa<CXXThisExpr>(E)) {
3498       if (AlignedThis) {
3499         Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3500             << 2 << E->getSourceRange();
3501         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3502             << getOpenMPClauseName(OMPC_aligned);
3503       }
3504       AlignedThis = E;
3505       continue;
3506     }
3507     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3508         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3509   }
3510   // The optional parameter of the aligned clause, alignment, must be a constant
3511   // positive integer expression. If no optional parameter is specified,
3512   // implementation-defined default alignments for SIMD instructions on the
3513   // target platforms are assumed.
3514   SmallVector<const Expr *, 4> NewAligns;
3515   for (Expr *E : Alignments) {
3516     ExprResult Align;
3517     if (E)
3518       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3519     NewAligns.push_back(Align.get());
3520   }
3521   // OpenMP [2.8.2, declare simd construct, Description]
3522   // The linear clause declares one or more list items to be private to a SIMD
3523   // lane and to have a linear relationship with respect to the iteration space
3524   // of a loop.
3525   // The special this pointer can be used as if was one of the arguments to the
3526   // function in any of the linear, aligned, or uniform clauses.
3527   // When a linear-step expression is specified in a linear clause it must be
3528   // either a constant integer expression or an integer-typed parameter that is
3529   // specified in a uniform clause on the directive.
3530   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3531   const bool IsUniformedThis = UniformedLinearThis != nullptr;
3532   auto MI = LinModifiers.begin();
3533   for (const Expr *E : Linears) {
3534     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3535     ++MI;
3536     E = E->IgnoreParenImpCasts();
3537     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3538       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3539         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3540         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3541             FD->getParamDecl(PVD->getFunctionScopeIndex())
3542                     ->getCanonicalDecl() == CanonPVD) {
3543           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
3544           // A list-item cannot appear in more than one linear clause.
3545           if (LinearArgs.count(CanonPVD) > 0) {
3546             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3547                 << getOpenMPClauseName(OMPC_linear)
3548                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3549             Diag(LinearArgs[CanonPVD]->getExprLoc(),
3550                  diag::note_omp_explicit_dsa)
3551                 << getOpenMPClauseName(OMPC_linear);
3552             continue;
3553           }
3554           // Each argument can appear in at most one uniform or linear clause.
3555           if (UniformedArgs.count(CanonPVD) > 0) {
3556             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3557                 << getOpenMPClauseName(OMPC_linear)
3558                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3559             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3560                  diag::note_omp_explicit_dsa)
3561                 << getOpenMPClauseName(OMPC_uniform);
3562             continue;
3563           }
3564           LinearArgs[CanonPVD] = E;
3565           if (E->isValueDependent() || E->isTypeDependent() ||
3566               E->isInstantiationDependent() ||
3567               E->containsUnexpandedParameterPack())
3568             continue;
3569           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3570                                       PVD->getOriginalType());
3571           continue;
3572         }
3573       }
3574     if (isa<CXXThisExpr>(E)) {
3575       if (UniformedLinearThis) {
3576         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3577             << getOpenMPClauseName(OMPC_linear)
3578             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3579             << E->getSourceRange();
3580         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3581             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3582                                                    : OMPC_linear);
3583         continue;
3584       }
3585       UniformedLinearThis = E;
3586       if (E->isValueDependent() || E->isTypeDependent() ||
3587           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3588         continue;
3589       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3590                                   E->getType());
3591       continue;
3592     }
3593     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3594         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3595   }
3596   Expr *Step = nullptr;
3597   Expr *NewStep = nullptr;
3598   SmallVector<Expr *, 4> NewSteps;
3599   for (Expr *E : Steps) {
3600     // Skip the same step expression, it was checked already.
3601     if (Step == E || !E) {
3602       NewSteps.push_back(E ? NewStep : nullptr);
3603       continue;
3604     }
3605     Step = E;
3606     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3607       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3608         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3609         if (UniformedArgs.count(CanonPVD) == 0) {
3610           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3611               << Step->getSourceRange();
3612         } else if (E->isValueDependent() || E->isTypeDependent() ||
3613                    E->isInstantiationDependent() ||
3614                    E->containsUnexpandedParameterPack() ||
3615                    CanonPVD->getType()->hasIntegerRepresentation()) {
3616           NewSteps.push_back(Step);
3617         } else {
3618           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3619               << Step->getSourceRange();
3620         }
3621         continue;
3622       }
3623     NewStep = Step;
3624     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3625         !Step->isInstantiationDependent() &&
3626         !Step->containsUnexpandedParameterPack()) {
3627       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3628                     .get();
3629       if (NewStep)
3630         NewStep = VerifyIntegerConstantExpression(NewStep).get();
3631     }
3632     NewSteps.push_back(NewStep);
3633   }
3634   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3635       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3636       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3637       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3638       const_cast<Expr **>(Linears.data()), Linears.size(),
3639       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3640       NewSteps.data(), NewSteps.size(), SR);
3641   ADecl->addAttr(NewAttr);
3642   return ConvertDeclToDeclGroup(ADecl);
3643 }
3644 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)3645 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3646                                               Stmt *AStmt,
3647                                               SourceLocation StartLoc,
3648                                               SourceLocation EndLoc) {
3649   if (!AStmt)
3650     return StmtError();
3651 
3652   auto *CS = cast<CapturedStmt>(AStmt);
3653   // 1.2.2 OpenMP Language Terminology
3654   // Structured block - An executable statement with a single entry at the
3655   // top and a single exit at the bottom.
3656   // The point of exit cannot be a branch out of the structured block.
3657   // longjmp() and throw() must not violate the entry/exit criteria.
3658   CS->getCapturedDecl()->setNothrow();
3659 
3660   setFunctionHasBranchProtectedScope();
3661 
3662   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3663                                       DSAStack->isCancelRegion());
3664 }
3665 
3666 namespace {
3667 /// Helper class for checking canonical form of the OpenMP loops and
3668 /// extracting iteration space of each loop in the loop nest, that will be used
3669 /// for IR generation.
3670 class OpenMPIterationSpaceChecker {
3671   /// Reference to Sema.
3672   Sema &SemaRef;
3673   /// A location for diagnostics (when there is no some better location).
3674   SourceLocation DefaultLoc;
3675   /// A location for diagnostics (when increment is not compatible).
3676   SourceLocation ConditionLoc;
3677   /// A source location for referring to loop init later.
3678   SourceRange InitSrcRange;
3679   /// A source location for referring to condition later.
3680   SourceRange ConditionSrcRange;
3681   /// A source location for referring to increment later.
3682   SourceRange IncrementSrcRange;
3683   /// Loop variable.
3684   ValueDecl *LCDecl = nullptr;
3685   /// Reference to loop variable.
3686   Expr *LCRef = nullptr;
3687   /// Lower bound (initializer for the var).
3688   Expr *LB = nullptr;
3689   /// Upper bound.
3690   Expr *UB = nullptr;
3691   /// Loop step (increment).
3692   Expr *Step = nullptr;
3693   /// This flag is true when condition is one of:
3694   ///   Var <  UB
3695   ///   Var <= UB
3696   ///   UB  >  Var
3697   ///   UB  >= Var
3698   bool TestIsLessOp = false;
3699   /// This flag is true when condition is strict ( < or > ).
3700   bool TestIsStrictOp = false;
3701   /// This flag is true when step is subtracted on each iteration.
3702   bool SubtractStep = false;
3703 
3704 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,SourceLocation DefaultLoc)3705   OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3706       : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3707   /// Check init-expr for canonical loop form and save loop counter
3708   /// variable - #Var and its initialization value - #LB.
3709   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
3710   /// Check test-expr for canonical form, save upper-bound (#UB), flags
3711   /// for less/greater and for strict/non-strict comparison.
3712   bool checkAndSetCond(Expr *S);
3713   /// Check incr-expr for canonical loop form and return true if it
3714   /// does not conform, otherwise save loop step (#Step).
3715   bool checkAndSetInc(Expr *S);
3716   /// Return the loop counter variable.
getLoopDecl() const3717   ValueDecl *getLoopDecl() const { return LCDecl; }
3718   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const3719   Expr *getLoopDeclRefExpr() const { return LCRef; }
3720   /// Source range of the loop init.
getInitSrcRange() const3721   SourceRange getInitSrcRange() const { return InitSrcRange; }
3722   /// Source range of the loop condition.
getConditionSrcRange() const3723   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
3724   /// Source range of the loop increment.
getIncrementSrcRange() const3725   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
3726   /// True if the step should be subtracted.
shouldSubtractStep() const3727   bool shouldSubtractStep() const { return SubtractStep; }
3728   /// Build the expression to calculate the number of iterations.
3729   Expr *buildNumIterations(
3730       Scope *S, const bool LimitedType,
3731       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
3732   /// Build the precondition expression for the loops.
3733   Expr *
3734   buildPreCond(Scope *S, Expr *Cond,
3735                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
3736   /// Build reference expression to the counter be used for codegen.
3737   DeclRefExpr *
3738   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3739                   DSAStackTy &DSA) const;
3740   /// Build reference expression to the private counter be used for
3741   /// codegen.
3742   Expr *buildPrivateCounterVar() const;
3743   /// Build initialization of the counter be used for codegen.
3744   Expr *buildCounterInit() const;
3745   /// Build step of the counter be used for codegen.
3746   Expr *buildCounterStep() const;
3747   /// Build loop data with counter value for depend clauses in ordered
3748   /// directives.
3749   Expr *
3750   buildOrderedLoopData(Scope *S, Expr *Counter,
3751                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3752                        SourceLocation Loc, Expr *Inc = nullptr,
3753                        OverloadedOperatorKind OOK = OO_Amp);
3754   /// Return true if any expression is dependent.
3755   bool dependent() const;
3756 
3757 private:
3758   /// Check the right-hand side of an assignment in the increment
3759   /// expression.
3760   bool checkAndSetIncRHS(Expr *RHS);
3761   /// Helper to set loop counter variable and its initializer.
3762   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3763   /// Helper to set upper bound.
3764   bool setUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3765              SourceLocation SL);
3766   /// Helper to set loop increment.
3767   bool setStep(Expr *NewStep, bool Subtract);
3768 };
3769 
dependent() const3770 bool OpenMPIterationSpaceChecker::dependent() const {
3771   if (!LCDecl) {
3772     assert(!LB && !UB && !Step);
3773     return false;
3774   }
3775   return LCDecl->getType()->isDependentType() ||
3776          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3777          (Step && Step->isValueDependent());
3778 }
3779 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB)3780 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
3781                                                  Expr *NewLCRefExpr,
3782                                                  Expr *NewLB) {
3783   // State consistency checking to ensure correct usage.
3784   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
3785          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3786   if (!NewLCDecl || !NewLB)
3787     return true;
3788   LCDecl = getCanonicalDecl(NewLCDecl);
3789   LCRef = NewLCRefExpr;
3790   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3791     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3792       if ((Ctor->isCopyOrMoveConstructor() ||
3793            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3794           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3795         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3796   LB = NewLB;
3797   return false;
3798 }
3799 
setUB(Expr * NewUB,bool LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)3800 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, bool LessOp, bool StrictOp,
3801                                         SourceRange SR, SourceLocation SL) {
3802   // State consistency checking to ensure correct usage.
3803   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
3804          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3805   if (!NewUB)
3806     return true;
3807   UB = NewUB;
3808   TestIsLessOp = LessOp;
3809   TestIsStrictOp = StrictOp;
3810   ConditionSrcRange = SR;
3811   ConditionLoc = SL;
3812   return false;
3813 }
3814 
setStep(Expr * NewStep,bool Subtract)3815 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
3816   // State consistency checking to ensure correct usage.
3817   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
3818   if (!NewStep)
3819     return true;
3820   if (!NewStep->isValueDependent()) {
3821     // Check that the step is integer expression.
3822     SourceLocation StepLoc = NewStep->getLocStart();
3823     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
3824         StepLoc, getExprAsWritten(NewStep));
3825     if (Val.isInvalid())
3826       return true;
3827     NewStep = Val.get();
3828 
3829     // OpenMP [2.6, Canonical Loop Form, Restrictions]
3830     //  If test-expr is of form var relational-op b and relational-op is < or
3831     //  <= then incr-expr must cause var to increase on each iteration of the
3832     //  loop. If test-expr is of form var relational-op b and relational-op is
3833     //  > or >= then incr-expr must cause var to decrease on each iteration of
3834     //  the loop.
3835     //  If test-expr is of form b relational-op var and relational-op is < or
3836     //  <= then incr-expr must cause var to decrease on each iteration of the
3837     //  loop. If test-expr is of form b relational-op var and relational-op is
3838     //  > or >= then incr-expr must cause var to increase on each iteration of
3839     //  the loop.
3840     llvm::APSInt Result;
3841     bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3842     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3843     bool IsConstNeg =
3844         IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3845     bool IsConstPos =
3846         IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3847     bool IsConstZero = IsConstant && !Result.getBoolValue();
3848     if (UB && (IsConstZero ||
3849                (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3850                              : (IsConstPos || (IsUnsigned && !Subtract))))) {
3851       SemaRef.Diag(NewStep->getExprLoc(),
3852                    diag::err_omp_loop_incr_not_compatible)
3853           << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3854       SemaRef.Diag(ConditionLoc,
3855                    diag::note_omp_loop_cond_requres_compatible_incr)
3856           << TestIsLessOp << ConditionSrcRange;
3857       return true;
3858     }
3859     if (TestIsLessOp == Subtract) {
3860       NewStep =
3861           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3862               .get();
3863       Subtract = !Subtract;
3864     }
3865   }
3866 
3867   Step = NewStep;
3868   SubtractStep = Subtract;
3869   return false;
3870 }
3871 
checkAndSetInit(Stmt * S,bool EmitDiags)3872 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
3873   // Check init-expr for canonical loop form and save loop counter
3874   // variable - #Var and its initialization value - #LB.
3875   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3876   //   var = lb
3877   //   integer-type var = lb
3878   //   random-access-iterator-type var = lb
3879   //   pointer-type var = lb
3880   //
3881   if (!S) {
3882     if (EmitDiags) {
3883       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3884     }
3885     return true;
3886   }
3887   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3888     if (!ExprTemp->cleanupsHaveSideEffects())
3889       S = ExprTemp->getSubExpr();
3890 
3891   InitSrcRange = S->getSourceRange();
3892   if (Expr *E = dyn_cast<Expr>(S))
3893     S = E->IgnoreParens();
3894   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3895     if (BO->getOpcode() == BO_Assign) {
3896       Expr *LHS = BO->getLHS()->IgnoreParens();
3897       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3898         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3899           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3900             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3901         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3902       }
3903       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3904         if (ME->isArrow() &&
3905             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3906           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3907       }
3908     }
3909   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3910     if (DS->isSingleDecl()) {
3911       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3912         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3913           // Accept non-canonical init form here but emit ext. warning.
3914           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3915             SemaRef.Diag(S->getLocStart(),
3916                          diag::ext_omp_loop_not_canonical_init)
3917                 << S->getSourceRange();
3918           return setLCDeclAndLB(
3919               Var,
3920               buildDeclRefExpr(SemaRef, Var,
3921                                Var->getType().getNonReferenceType(),
3922                                DS->getLocStart()),
3923               Var->getInit());
3924         }
3925       }
3926     }
3927   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3928     if (CE->getOperator() == OO_Equal) {
3929       Expr *LHS = CE->getArg(0);
3930       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3931         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3932           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3933             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3934         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3935       }
3936       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3937         if (ME->isArrow() &&
3938             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3939           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3940       }
3941     }
3942   }
3943 
3944   if (dependent() || SemaRef.CurContext->isDependentContext())
3945     return false;
3946   if (EmitDiags) {
3947     SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3948         << S->getSourceRange();
3949   }
3950   return true;
3951 }
3952 
3953 /// Ignore parenthesizes, implicit casts, copy constructor and return the
3954 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)3955 static const ValueDecl *getInitLCDecl(const Expr *E) {
3956   if (!E)
3957     return nullptr;
3958   E = getExprAsWritten(E);
3959   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3960     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3961       if ((Ctor->isCopyOrMoveConstructor() ||
3962            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3963           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3964         E = CE->getArg(0)->IgnoreParenImpCasts();
3965   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3966     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3967       return getCanonicalDecl(VD);
3968   }
3969   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
3970     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3971       return getCanonicalDecl(ME->getMemberDecl());
3972   return nullptr;
3973 }
3974 
checkAndSetCond(Expr * S)3975 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
3976   // Check test-expr for canonical form, save upper-bound UB, flags for
3977   // less/greater and for strict/non-strict comparison.
3978   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3979   //   var relational-op b
3980   //   b relational-op var
3981   //
3982   if (!S) {
3983     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3984     return true;
3985   }
3986   S = getExprAsWritten(S);
3987   SourceLocation CondLoc = S->getLocStart();
3988   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3989     if (BO->isRelationalOp()) {
3990       if (getInitLCDecl(BO->getLHS()) == LCDecl)
3991         return setUB(BO->getRHS(),
3992                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3993                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3994                      BO->getSourceRange(), BO->getOperatorLoc());
3995       if (getInitLCDecl(BO->getRHS()) == LCDecl)
3996         return setUB(BO->getLHS(),
3997                      (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3998                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3999                      BO->getSourceRange(), BO->getOperatorLoc());
4000     }
4001   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4002     if (CE->getNumArgs() == 2) {
4003       auto Op = CE->getOperator();
4004       switch (Op) {
4005       case OO_Greater:
4006       case OO_GreaterEqual:
4007       case OO_Less:
4008       case OO_LessEqual:
4009         if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4010           return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4011                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4012                        CE->getOperatorLoc());
4013         if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4014           return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4015                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4016                        CE->getOperatorLoc());
4017         break;
4018       default:
4019         break;
4020       }
4021     }
4022   }
4023   if (dependent() || SemaRef.CurContext->isDependentContext())
4024     return false;
4025   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4026       << S->getSourceRange() << LCDecl;
4027   return true;
4028 }
4029 
checkAndSetIncRHS(Expr * RHS)4030 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
4031   // RHS of canonical loop form increment can be:
4032   //   var + incr
4033   //   incr + var
4034   //   var - incr
4035   //
4036   RHS = RHS->IgnoreParenImpCasts();
4037   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4038     if (BO->isAdditiveOp()) {
4039       bool IsAdd = BO->getOpcode() == BO_Add;
4040       if (getInitLCDecl(BO->getLHS()) == LCDecl)
4041         return setStep(BO->getRHS(), !IsAdd);
4042       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4043         return setStep(BO->getLHS(), /*Subtract=*/false);
4044     }
4045   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4046     bool IsAdd = CE->getOperator() == OO_Plus;
4047     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4048       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4049         return setStep(CE->getArg(1), !IsAdd);
4050       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4051         return setStep(CE->getArg(0), /*Subtract=*/false);
4052     }
4053   }
4054   if (dependent() || SemaRef.CurContext->isDependentContext())
4055     return false;
4056   SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4057       << RHS->getSourceRange() << LCDecl;
4058   return true;
4059 }
4060 
checkAndSetInc(Expr * S)4061 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
4062   // Check incr-expr for canonical loop form and return true if it
4063   // does not conform.
4064   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4065   //   ++var
4066   //   var++
4067   //   --var
4068   //   var--
4069   //   var += incr
4070   //   var -= incr
4071   //   var = var + incr
4072   //   var = incr + var
4073   //   var = var - incr
4074   //
4075   if (!S) {
4076     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4077     return true;
4078   }
4079   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4080     if (!ExprTemp->cleanupsHaveSideEffects())
4081       S = ExprTemp->getSubExpr();
4082 
4083   IncrementSrcRange = S->getSourceRange();
4084   S = S->IgnoreParens();
4085   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
4086     if (UO->isIncrementDecrementOp() &&
4087         getInitLCDecl(UO->getSubExpr()) == LCDecl)
4088       return setStep(SemaRef
4089                          .ActOnIntegerConstant(UO->getLocStart(),
4090                                                (UO->isDecrementOp() ? -1 : 1))
4091                          .get(),
4092                      /*Subtract=*/false);
4093   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4094     switch (BO->getOpcode()) {
4095     case BO_AddAssign:
4096     case BO_SubAssign:
4097       if (getInitLCDecl(BO->getLHS()) == LCDecl)
4098         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4099       break;
4100     case BO_Assign:
4101       if (getInitLCDecl(BO->getLHS()) == LCDecl)
4102         return checkAndSetIncRHS(BO->getRHS());
4103       break;
4104     default:
4105       break;
4106     }
4107   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4108     switch (CE->getOperator()) {
4109     case OO_PlusPlus:
4110     case OO_MinusMinus:
4111       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4112         return setStep(SemaRef
4113                            .ActOnIntegerConstant(
4114                                CE->getLocStart(),
4115                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4116                            .get(),
4117                        /*Subtract=*/false);
4118       break;
4119     case OO_PlusEqual:
4120     case OO_MinusEqual:
4121       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4122         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4123       break;
4124     case OO_Equal:
4125       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4126         return checkAndSetIncRHS(CE->getArg(1));
4127       break;
4128     default:
4129       break;
4130     }
4131   }
4132   if (dependent() || SemaRef.CurContext->isDependentContext())
4133     return false;
4134   SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4135       << S->getSourceRange() << LCDecl;
4136   return true;
4137 }
4138 
4139 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4140 tryBuildCapture(Sema &SemaRef, Expr *Capture,
4141                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4142   if (SemaRef.CurContext->isDependentContext())
4143     return ExprResult(Capture);
4144   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4145     return SemaRef.PerformImplicitConversion(
4146         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4147         /*AllowExplicit=*/true);
4148   auto I = Captures.find(Capture);
4149   if (I != Captures.end())
4150     return buildCapture(SemaRef, Capture, I->second);
4151   DeclRefExpr *Ref = nullptr;
4152   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4153   Captures[Capture] = Ref;
4154   return Res;
4155 }
4156 
4157 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,const bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const4158 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4159     Scope *S, const bool LimitedType,
4160     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4161   ExprResult Diff;
4162   QualType VarType = LCDecl->getType().getNonReferenceType();
4163   if (VarType->isIntegerType() || VarType->isPointerType() ||
4164       SemaRef.getLangOpts().CPlusPlus) {
4165     // Upper - Lower
4166     Expr *UBExpr = TestIsLessOp ? UB : LB;
4167     Expr *LBExpr = TestIsLessOp ? LB : UB;
4168     Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4169     Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4170     if (!Upper || !Lower)
4171       return nullptr;
4172 
4173     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4174 
4175     if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4176       // BuildBinOp already emitted error, this one is to point user to upper
4177       // and lower bound, and to tell what is passed to 'operator-'.
4178       SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4179           << Upper->getSourceRange() << Lower->getSourceRange();
4180       return nullptr;
4181     }
4182   }
4183 
4184   if (!Diff.isUsable())
4185     return nullptr;
4186 
4187   // Upper - Lower [- 1]
4188   if (TestIsStrictOp)
4189     Diff = SemaRef.BuildBinOp(
4190         S, DefaultLoc, BO_Sub, Diff.get(),
4191         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4192   if (!Diff.isUsable())
4193     return nullptr;
4194 
4195   // Upper - Lower [- 1] + Step
4196   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4197   if (!NewStep.isUsable())
4198     return nullptr;
4199   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4200   if (!Diff.isUsable())
4201     return nullptr;
4202 
4203   // Parentheses (for dumping/debugging purposes only).
4204   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4205   if (!Diff.isUsable())
4206     return nullptr;
4207 
4208   // (Upper - Lower [- 1] + Step) / Step
4209   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4210   if (!Diff.isUsable())
4211     return nullptr;
4212 
4213   // OpenMP runtime requires 32-bit or 64-bit loop variables.
4214   QualType Type = Diff.get()->getType();
4215   ASTContext &C = SemaRef.Context;
4216   bool UseVarType = VarType->hasIntegerRepresentation() &&
4217                     C.getTypeSize(Type) > C.getTypeSize(VarType);
4218   if (!Type->isIntegerType() || UseVarType) {
4219     unsigned NewSize =
4220         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4221     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4222                                : Type->hasSignedIntegerRepresentation();
4223     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4224     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4225       Diff = SemaRef.PerformImplicitConversion(
4226           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4227       if (!Diff.isUsable())
4228         return nullptr;
4229     }
4230   }
4231   if (LimitedType) {
4232     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4233     if (NewSize != C.getTypeSize(Type)) {
4234       if (NewSize < C.getTypeSize(Type)) {
4235         assert(NewSize == 64 && "incorrect loop var size");
4236         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4237             << InitSrcRange << ConditionSrcRange;
4238       }
4239       QualType NewType = C.getIntTypeForBitwidth(
4240           NewSize, Type->hasSignedIntegerRepresentation() ||
4241                        C.getTypeSize(Type) < NewSize);
4242       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4243         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4244                                                  Sema::AA_Converting, true);
4245         if (!Diff.isUsable())
4246           return nullptr;
4247       }
4248     }
4249   }
4250 
4251   return Diff.get();
4252 }
4253 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const4254 Expr *OpenMPIterationSpaceChecker::buildPreCond(
4255     Scope *S, Expr *Cond,
4256     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4257   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4258   bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4259   SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4260 
4261   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4262   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4263   if (!NewLB.isUsable() || !NewUB.isUsable())
4264     return nullptr;
4265 
4266   ExprResult CondExpr =
4267       SemaRef.BuildBinOp(S, DefaultLoc,
4268                          TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4269                                       : (TestIsStrictOp ? BO_GT : BO_GE),
4270                          NewLB.get(), NewUB.get());
4271   if (CondExpr.isUsable()) {
4272     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4273                                                 SemaRef.Context.BoolTy))
4274       CondExpr = SemaRef.PerformImplicitConversion(
4275           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4276           /*AllowExplicit=*/true);
4277   }
4278   SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4279   // Otherwise use original loop conditon and evaluate it in runtime.
4280   return CondExpr.isUsable() ? CondExpr.get() : Cond;
4281 }
4282 
4283 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const4284 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4285     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4286     DSAStackTy &DSA) const {
4287   auto *VD = dyn_cast<VarDecl>(LCDecl);
4288   if (!VD) {
4289     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
4290     DeclRefExpr *Ref = buildDeclRefExpr(
4291         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4292     const DSAStackTy::DSAVarData Data =
4293         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4294     // If the loop control decl is explicitly marked as private, do not mark it
4295     // as captured again.
4296     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4297       Captures.insert(std::make_pair(LCRef, Ref));
4298     return Ref;
4299   }
4300   return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4301                           DefaultLoc);
4302 }
4303 
buildPrivateCounterVar() const4304 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
4305   if (LCDecl && !LCDecl->isInvalidDecl()) {
4306     QualType Type = LCDecl->getType().getNonReferenceType();
4307     VarDecl *PrivateVar = buildVarDecl(
4308         SemaRef, DefaultLoc, Type, LCDecl->getName(),
4309         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
4310         isa<VarDecl>(LCDecl)
4311             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
4312             : nullptr);
4313     if (PrivateVar->isInvalidDecl())
4314       return nullptr;
4315     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4316   }
4317   return nullptr;
4318 }
4319 
4320 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const4321 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
4322 
4323 /// Build step of the counter be used for codegen.
buildCounterStep() const4324 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
4325 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)4326 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4327     Scope *S, Expr *Counter,
4328     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
4329     Expr *Inc, OverloadedOperatorKind OOK) {
4330   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
4331   if (!Cnt)
4332     return nullptr;
4333   if (Inc) {
4334     assert((OOK == OO_Plus || OOK == OO_Minus) &&
4335            "Expected only + or - operations for depend clauses.");
4336     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
4337     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
4338     if (!Cnt)
4339       return nullptr;
4340   }
4341   ExprResult Diff;
4342   QualType VarType = LCDecl->getType().getNonReferenceType();
4343   if (VarType->isIntegerType() || VarType->isPointerType() ||
4344       SemaRef.getLangOpts().CPlusPlus) {
4345     // Upper - Lower
4346     Expr *Upper =
4347         TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4348     Expr *Lower =
4349         TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4350     if (!Upper || !Lower)
4351       return nullptr;
4352 
4353     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4354 
4355     if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4356       // BuildBinOp already emitted error, this one is to point user to upper
4357       // and lower bound, and to tell what is passed to 'operator-'.
4358       SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4359           << Upper->getSourceRange() << Lower->getSourceRange();
4360       return nullptr;
4361     }
4362   }
4363 
4364   if (!Diff.isUsable())
4365     return nullptr;
4366 
4367   // Parentheses (for dumping/debugging purposes only).
4368   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4369   if (!Diff.isUsable())
4370     return nullptr;
4371 
4372   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4373   if (!NewStep.isUsable())
4374     return nullptr;
4375   // (Upper - Lower) / Step
4376   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4377   if (!Diff.isUsable())
4378     return nullptr;
4379 
4380   return Diff.get();
4381 }
4382 
4383 /// Iteration space of a single for loop.
4384 struct LoopIterationSpace final {
4385   /// Condition of the loop.
4386   Expr *PreCond = nullptr;
4387   /// This expression calculates the number of iterations in the loop.
4388   /// It is always possible to calculate it before starting the loop.
4389   Expr *NumIterations = nullptr;
4390   /// The loop counter variable.
4391   Expr *CounterVar = nullptr;
4392   /// Private loop counter variable.
4393   Expr *PrivateCounterVar = nullptr;
4394   /// This is initializer for the initial value of #CounterVar.
4395   Expr *CounterInit = nullptr;
4396   /// This is step for the #CounterVar used to generate its update:
4397   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4398   Expr *CounterStep = nullptr;
4399   /// Should step be subtracted?
4400   bool Subtract = false;
4401   /// Source range of the loop init.
4402   SourceRange InitSrcRange;
4403   /// Source range of the loop condition.
4404   SourceRange CondSrcRange;
4405   /// Source range of the loop increment.
4406   SourceRange IncSrcRange;
4407 };
4408 
4409 } // namespace
4410 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)4411 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4412   assert(getLangOpts().OpenMP && "OpenMP is not active.");
4413   assert(Init && "Expected loop in canonical form.");
4414   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4415   if (AssociatedLoops > 0 &&
4416       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4417     OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4418     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
4419       if (ValueDecl *D = ISC.getLoopDecl()) {
4420         auto *VD = dyn_cast<VarDecl>(D);
4421         if (!VD) {
4422           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
4423             VD = Private;
4424           } else {
4425             DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
4426                                             /*WithInit=*/false);
4427             VD = cast<VarDecl>(Ref->getDecl());
4428           }
4429         }
4430         DSAStack->addLoopControlVariable(D, VD);
4431       }
4432     }
4433     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4434   }
4435 }
4436 
4437 /// Called on a for stmt to check and extract its iteration space
4438 /// 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,LoopIterationSpace & ResultIterSpace,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4439 static bool checkOpenMPIterationSpace(
4440     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4441     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4442     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
4443     Expr *OrderedLoopCountExpr,
4444     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4445     LoopIterationSpace &ResultIterSpace,
4446     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4447   // OpenMP [2.6, Canonical Loop Form]
4448   //   for (init-expr; test-expr; incr-expr) structured-block
4449   auto *For = dyn_cast_or_null<ForStmt>(S);
4450   if (!For) {
4451     SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4452         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4453         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
4454         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4455     if (TotalNestedLoopCount > 1) {
4456       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4457         SemaRef.Diag(DSA.getConstructLoc(),
4458                      diag::note_omp_collapse_ordered_expr)
4459             << 2 << CollapseLoopCountExpr->getSourceRange()
4460             << OrderedLoopCountExpr->getSourceRange();
4461       else if (CollapseLoopCountExpr)
4462         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4463                      diag::note_omp_collapse_ordered_expr)
4464             << 0 << CollapseLoopCountExpr->getSourceRange();
4465       else
4466         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4467                      diag::note_omp_collapse_ordered_expr)
4468             << 1 << OrderedLoopCountExpr->getSourceRange();
4469     }
4470     return true;
4471   }
4472   assert(For->getBody());
4473 
4474   OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4475 
4476   // Check init.
4477   Stmt *Init = For->getInit();
4478   if (ISC.checkAndSetInit(Init))
4479     return true;
4480 
4481   bool HasErrors = false;
4482 
4483   // Check loop variable's type.
4484   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
4485     Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4486 
4487     // OpenMP [2.6, Canonical Loop Form]
4488     // Var is one of the following:
4489     //   A variable of signed or unsigned integer type.
4490     //   For C++, a variable of a random access iterator type.
4491     //   For C, a variable of a pointer type.
4492     QualType VarType = LCDecl->getType().getNonReferenceType();
4493     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4494         !VarType->isPointerType() &&
4495         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4496       SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4497           << SemaRef.getLangOpts().CPlusPlus;
4498       HasErrors = true;
4499     }
4500 
4501     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4502     // a Construct
4503     // The loop iteration variable(s) in the associated for-loop(s) of a for or
4504     // parallel for construct is (are) private.
4505     // The loop iteration variable in the associated for-loop of a simd
4506     // construct with just one associated for-loop is linear with a
4507     // constant-linear-step that is the increment of the associated for-loop.
4508     // Exclude loop var from the list of variables with implicitly defined data
4509     // sharing attributes.
4510     VarsWithImplicitDSA.erase(LCDecl);
4511 
4512     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4513     // in a Construct, C/C++].
4514     // The loop iteration variable in the associated for-loop of a simd
4515     // construct with just one associated for-loop may be listed in a linear
4516     // clause with a constant-linear-step that is the increment of the
4517     // associated for-loop.
4518     // The loop iteration variable(s) in the associated for-loop(s) of a for or
4519     // parallel for construct may be listed in a private or lastprivate clause.
4520     DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4521     // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4522     // declared in the loop and it is predetermined as a private.
4523     OpenMPClauseKind PredeterminedCKind =
4524         isOpenMPSimdDirective(DKind)
4525             ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4526             : OMPC_private;
4527     if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4528           DVar.CKind != PredeterminedCKind) ||
4529          ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4530            isOpenMPDistributeDirective(DKind)) &&
4531           !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4532           DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4533         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4534       SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4535           << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4536           << getOpenMPClauseName(PredeterminedCKind);
4537       if (DVar.RefExpr == nullptr)
4538         DVar.CKind = PredeterminedCKind;
4539       reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4540       HasErrors = true;
4541     } else if (LoopDeclRefExpr != nullptr) {
4542       // Make the loop iteration variable private (for worksharing constructs),
4543       // linear (for simd directives with the only one associated loop) or
4544       // lastprivate (for simd directives with several collapsed or ordered
4545       // loops).
4546       if (DVar.CKind == OMPC_unknown)
4547         DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4548                           [](OpenMPDirectiveKind) -> bool { return true; },
4549                           /*FromParent=*/false);
4550       DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4551     }
4552 
4553     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4554 
4555     // Check test-expr.
4556     HasErrors |= ISC.checkAndSetCond(For->getCond());
4557 
4558     // Check incr-expr.
4559     HasErrors |= ISC.checkAndSetInc(For->getInc());
4560   }
4561 
4562   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4563     return HasErrors;
4564 
4565   // Build the loop's iteration space representation.
4566   ResultIterSpace.PreCond =
4567       ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4568   ResultIterSpace.NumIterations = ISC.buildNumIterations(
4569       DSA.getCurScope(),
4570       (isOpenMPWorksharingDirective(DKind) ||
4571        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4572       Captures);
4573   ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4574   ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4575   ResultIterSpace.CounterInit = ISC.buildCounterInit();
4576   ResultIterSpace.CounterStep = ISC.buildCounterStep();
4577   ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4578   ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4579   ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4580   ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4581 
4582   HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4583                 ResultIterSpace.NumIterations == nullptr ||
4584                 ResultIterSpace.CounterVar == nullptr ||
4585                 ResultIterSpace.PrivateCounterVar == nullptr ||
4586                 ResultIterSpace.CounterInit == nullptr ||
4587                 ResultIterSpace.CounterStep == nullptr);
4588   if (!HasErrors && DSA.isOrderedRegion()) {
4589     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4590       if (CurrentNestedLoopCount <
4591           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4592         DSA.getOrderedRegionParam().second->setLoopNumIterations(
4593             CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4594         DSA.getOrderedRegionParam().second->setLoopCounter(
4595             CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4596       }
4597     }
4598     for (auto &Pair : DSA.getDoacrossDependClauses()) {
4599       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4600         // Erroneous case - clause has some problems.
4601         continue;
4602       }
4603       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4604           Pair.second.size() <= CurrentNestedLoopCount) {
4605         // Erroneous case - clause has some problems.
4606         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
4607         continue;
4608       }
4609       Expr *CntValue;
4610       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4611         CntValue = ISC.buildOrderedLoopData(
4612             DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4613             Pair.first->getDependencyLoc());
4614       else
4615         CntValue = ISC.buildOrderedLoopData(
4616             DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4617             Pair.first->getDependencyLoc(),
4618             Pair.second[CurrentNestedLoopCount].first,
4619             Pair.second[CurrentNestedLoopCount].second);
4620       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4621     }
4622   }
4623 
4624   return HasErrors;
4625 }
4626 
4627 /// Build 'VarRef = Start.
4628 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4629 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4630                  ExprResult Start,
4631                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4632   // Build 'VarRef = Start.
4633   ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4634   if (!NewStart.isUsable())
4635     return ExprError();
4636   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4637                                    VarRef.get()->getType())) {
4638     NewStart = SemaRef.PerformImplicitConversion(
4639         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4640         /*AllowExplicit=*/true);
4641     if (!NewStart.isUsable())
4642       return ExprError();
4643   }
4644 
4645   ExprResult Init =
4646       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4647   return Init;
4648 }
4649 
4650 /// Build 'VarRef = Start + Iter * Step'.
buildCounterUpdate(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,ExprResult Iter,ExprResult Step,bool Subtract,llvm::MapVector<const Expr *,DeclRefExpr * > * Captures=nullptr)4651 static ExprResult buildCounterUpdate(
4652     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4653     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
4654     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
4655   // Add parentheses (for debugging purposes only).
4656   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4657   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4658       !Step.isUsable())
4659     return ExprError();
4660 
4661   ExprResult NewStep = Step;
4662   if (Captures)
4663     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4664   if (NewStep.isInvalid())
4665     return ExprError();
4666   ExprResult Update =
4667       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4668   if (!Update.isUsable())
4669     return ExprError();
4670 
4671   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4672   // 'VarRef = Start (+|-) Iter * Step'.
4673   ExprResult NewStart = Start;
4674   if (Captures)
4675     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4676   if (NewStart.isInvalid())
4677     return ExprError();
4678 
4679   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4680   ExprResult SavedUpdate = Update;
4681   ExprResult UpdateVal;
4682   if (VarRef.get()->getType()->isOverloadableType() ||
4683       NewStart.get()->getType()->isOverloadableType() ||
4684       Update.get()->getType()->isOverloadableType()) {
4685     bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4686     SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4687     Update =
4688         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4689     if (Update.isUsable()) {
4690       UpdateVal =
4691           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4692                              VarRef.get(), SavedUpdate.get());
4693       if (UpdateVal.isUsable()) {
4694         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4695                                             UpdateVal.get());
4696       }
4697     }
4698     SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4699   }
4700 
4701   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4702   if (!Update.isUsable() || !UpdateVal.isUsable()) {
4703     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4704                                 NewStart.get(), SavedUpdate.get());
4705     if (!Update.isUsable())
4706       return ExprError();
4707 
4708     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4709                                      VarRef.get()->getType())) {
4710       Update = SemaRef.PerformImplicitConversion(
4711           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4712       if (!Update.isUsable())
4713         return ExprError();
4714     }
4715 
4716     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4717   }
4718   return Update;
4719 }
4720 
4721 /// Convert integer expression \a E to make it have at least \a Bits
4722 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)4723 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4724   if (E == nullptr)
4725     return ExprError();
4726   ASTContext &C = SemaRef.Context;
4727   QualType OldType = E->getType();
4728   unsigned HasBits = C.getTypeSize(OldType);
4729   if (HasBits >= Bits)
4730     return ExprResult(E);
4731   // OK to convert to signed, because new type has more bits than old.
4732   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4733   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4734                                            true);
4735 }
4736 
4737 /// Check if the given expression \a E is a constant integer that fits
4738 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)4739 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
4740   if (E == nullptr)
4741     return false;
4742   llvm::APSInt Result;
4743   if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4744     return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4745   return false;
4746 }
4747 
4748 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)4749 static Stmt *buildPreInits(ASTContext &Context,
4750                            MutableArrayRef<Decl *> PreInits) {
4751   if (!PreInits.empty()) {
4752     return new (Context) DeclStmt(
4753         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4754         SourceLocation(), SourceLocation());
4755   }
4756   return nullptr;
4757 }
4758 
4759 /// Build preinits statement for the given declarations.
4760 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)4761 buildPreInits(ASTContext &Context,
4762               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4763   if (!Captures.empty()) {
4764     SmallVector<Decl *, 16> PreInits;
4765     for (const auto &Pair : Captures)
4766       PreInits.push_back(Pair.second->getDecl());
4767     return buildPreInits(Context, PreInits);
4768   }
4769   return nullptr;
4770 }
4771 
4772 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)4773 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4774   Expr *PostUpdate = nullptr;
4775   if (!PostUpdates.empty()) {
4776     for (Expr *E : PostUpdates) {
4777       Expr *ConvE = S.BuildCStyleCastExpr(
4778                          E->getExprLoc(),
4779                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
4780                          E->getExprLoc(), E)
4781                         .get();
4782       PostUpdate = PostUpdate
4783                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4784                                               PostUpdate, ConvE)
4785                              .get()
4786                        : ConvE;
4787     }
4788   }
4789   return PostUpdate;
4790 }
4791 
4792 /// Called on a for stmt to check itself and nested loops (if any).
4793 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4794 /// number of collapsed loops otherwise.
4795 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopDirective::HelperExprs & Built)4796 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4797                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4798                 DSAStackTy &DSA,
4799                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4800                 OMPLoopDirective::HelperExprs &Built) {
4801   unsigned NestedLoopCount = 1;
4802   if (CollapseLoopCountExpr) {
4803     // Found 'collapse' clause - calculate collapse number.
4804     llvm::APSInt Result;
4805     if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4806       NestedLoopCount = Result.getLimitedValue();
4807   }
4808   unsigned OrderedLoopCount = 1;
4809   if (OrderedLoopCountExpr) {
4810     // Found 'ordered' clause - calculate collapse number.
4811     llvm::APSInt Result;
4812     if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4813       if (Result.getLimitedValue() < NestedLoopCount) {
4814         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4815                      diag::err_omp_wrong_ordered_loop_count)
4816             << OrderedLoopCountExpr->getSourceRange();
4817         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4818                      diag::note_collapse_loop_count)
4819             << CollapseLoopCountExpr->getSourceRange();
4820       }
4821       OrderedLoopCount = Result.getLimitedValue();
4822     }
4823   }
4824   // This is helper routine for loop directives (e.g., 'for', 'simd',
4825   // 'for simd', etc.).
4826   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
4827   SmallVector<LoopIterationSpace, 4> IterSpaces;
4828   IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
4829   Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4830   for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4831     if (checkOpenMPIterationSpace(
4832             DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4833             std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4834             OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4835             Captures))
4836       return 0;
4837     // Move on to the next nested for loop, or to the loop body.
4838     // OpenMP [2.8.1, simd construct, Restrictions]
4839     // All loops associated with the construct must be perfectly nested; that
4840     // is, there must be no intervening code nor any OpenMP directive between
4841     // any two loops.
4842     CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4843   }
4844   for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
4845     if (checkOpenMPIterationSpace(
4846             DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4847             std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4848             OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4849             Captures))
4850       return 0;
4851     if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
4852       // Handle initialization of captured loop iterator variables.
4853       auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
4854       if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
4855         Captures[DRE] = DRE;
4856       }
4857     }
4858     // Move on to the next nested for loop, or to the loop body.
4859     // OpenMP [2.8.1, simd construct, Restrictions]
4860     // All loops associated with the construct must be perfectly nested; that
4861     // is, there must be no intervening code nor any OpenMP directive between
4862     // any two loops.
4863     CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4864   }
4865 
4866   Built.clear(/* size */ NestedLoopCount);
4867 
4868   if (SemaRef.CurContext->isDependentContext())
4869     return NestedLoopCount;
4870 
4871   // An example of what is generated for the following code:
4872   //
4873   //   #pragma omp simd collapse(2) ordered(2)
4874   //   for (i = 0; i < NI; ++i)
4875   //     for (k = 0; k < NK; ++k)
4876   //       for (j = J0; j < NJ; j+=2) {
4877   //         <loop body>
4878   //       }
4879   //
4880   // We generate the code below.
4881   // Note: the loop body may be outlined in CodeGen.
4882   // Note: some counters may be C++ classes, operator- is used to find number of
4883   // iterations and operator+= to calculate counter value.
4884   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4885   // or i64 is currently supported).
4886   //
4887   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4888   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4889   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4890   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4891   //     // similar updates for vars in clauses (e.g. 'linear')
4892   //     <loop body (using local i and j)>
4893   //   }
4894   //   i = NI; // assign final values of counters
4895   //   j = NJ;
4896   //
4897 
4898   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4899   // the iteration counts of the collapsed for loops.
4900   // Precondition tests if there is at least one iteration (all conditions are
4901   // true).
4902   auto PreCond = ExprResult(IterSpaces[0].PreCond);
4903   Expr *N0 = IterSpaces[0].NumIterations;
4904   ExprResult LastIteration32 =
4905       widenIterationCount(/*Bits=*/32,
4906                           SemaRef
4907                               .PerformImplicitConversion(
4908                                   N0->IgnoreImpCasts(), N0->getType(),
4909                                   Sema::AA_Converting, /*AllowExplicit=*/true)
4910                               .get(),
4911                           SemaRef);
4912   ExprResult LastIteration64 = widenIterationCount(
4913       /*Bits=*/64,
4914       SemaRef
4915           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
4916                                      Sema::AA_Converting,
4917                                      /*AllowExplicit=*/true)
4918           .get(),
4919       SemaRef);
4920 
4921   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4922     return NestedLoopCount;
4923 
4924   ASTContext &C = SemaRef.Context;
4925   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4926 
4927   Scope *CurScope = DSA.getCurScope();
4928   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4929     if (PreCond.isUsable()) {
4930       PreCond =
4931           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4932                              PreCond.get(), IterSpaces[Cnt].PreCond);
4933     }
4934     Expr *N = IterSpaces[Cnt].NumIterations;
4935     SourceLocation Loc = N->getExprLoc();
4936     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4937     if (LastIteration32.isUsable())
4938       LastIteration32 = SemaRef.BuildBinOp(
4939           CurScope, Loc, BO_Mul, LastIteration32.get(),
4940           SemaRef
4941               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4942                                          Sema::AA_Converting,
4943                                          /*AllowExplicit=*/true)
4944               .get());
4945     if (LastIteration64.isUsable())
4946       LastIteration64 = SemaRef.BuildBinOp(
4947           CurScope, Loc, BO_Mul, LastIteration64.get(),
4948           SemaRef
4949               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4950                                          Sema::AA_Converting,
4951                                          /*AllowExplicit=*/true)
4952               .get());
4953   }
4954 
4955   // Choose either the 32-bit or 64-bit version.
4956   ExprResult LastIteration = LastIteration64;
4957   if (LastIteration32.isUsable() &&
4958       C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4959       (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4960        fitsInto(
4961            /*Bits=*/32,
4962            LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4963            LastIteration64.get(), SemaRef)))
4964     LastIteration = LastIteration32;
4965   QualType VType = LastIteration.get()->getType();
4966   QualType RealVType = VType;
4967   QualType StrideVType = VType;
4968   if (isOpenMPTaskLoopDirective(DKind)) {
4969     VType =
4970         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4971     StrideVType =
4972         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4973   }
4974 
4975   if (!LastIteration.isUsable())
4976     return 0;
4977 
4978   // Save the number of iterations.
4979   ExprResult NumIterations = LastIteration;
4980   {
4981     LastIteration = SemaRef.BuildBinOp(
4982         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4983         LastIteration.get(),
4984         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4985     if (!LastIteration.isUsable())
4986       return 0;
4987   }
4988 
4989   // Calculate the last iteration number beforehand instead of doing this on
4990   // each iteration. Do not do this if the number of iterations may be kfold-ed.
4991   llvm::APSInt Result;
4992   bool IsConstant =
4993       LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4994   ExprResult CalcLastIteration;
4995   if (!IsConstant) {
4996     ExprResult SaveRef =
4997         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4998     LastIteration = SaveRef;
4999 
5000     // Prepare SaveRef + 1.
5001     NumIterations = SemaRef.BuildBinOp(
5002         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
5003         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5004     if (!NumIterations.isUsable())
5005       return 0;
5006   }
5007 
5008   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5009 
5010   // Build variables passed into runtime, necessary for worksharing directives.
5011   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5012   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5013       isOpenMPDistributeDirective(DKind)) {
5014     // Lower bound variable, initialized with zero.
5015     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
5016     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
5017     SemaRef.AddInitializerToDecl(LBDecl,
5018                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5019                                  /*DirectInit*/ false);
5020 
5021     // Upper bound variable, initialized with last iteration number.
5022     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
5023     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
5024     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
5025                                  /*DirectInit*/ false);
5026 
5027     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5028     // This will be used to implement clause 'lastprivate'.
5029     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
5030     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
5031     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
5032     SemaRef.AddInitializerToDecl(ILDecl,
5033                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5034                                  /*DirectInit*/ false);
5035 
5036     // Stride variable returned by runtime (we initialize it to 1 by default).
5037     VarDecl *STDecl =
5038         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
5039     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
5040     SemaRef.AddInitializerToDecl(STDecl,
5041                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
5042                                  /*DirectInit*/ false);
5043 
5044     // Build expression: UB = min(UB, LastIteration)
5045     // It is necessary for CodeGen of directives with static scheduling.
5046     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
5047                                                 UB.get(), LastIteration.get());
5048     ExprResult CondOp = SemaRef.ActOnConditionalOp(
5049         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
5050         LastIteration.get(), UB.get());
5051     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
5052                              CondOp.get());
5053     EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
5054 
5055     // If we have a combined directive that combines 'distribute', 'for' or
5056     // 'simd' we need to be able to access the bounds of the schedule of the
5057     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5058     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5059     if (isOpenMPLoopBoundSharingDirective(DKind)) {
5060       // Lower bound variable, initialized with zero.
5061       VarDecl *CombLBDecl =
5062           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
5063       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
5064       SemaRef.AddInitializerToDecl(
5065           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5066           /*DirectInit*/ false);
5067 
5068       // Upper bound variable, initialized with last iteration number.
5069       VarDecl *CombUBDecl =
5070           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
5071       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
5072       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
5073                                    /*DirectInit*/ false);
5074 
5075       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
5076           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
5077       ExprResult CombCondOp =
5078           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
5079                                      LastIteration.get(), CombUB.get());
5080       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
5081                                    CombCondOp.get());
5082       CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
5083 
5084       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5085       // We expect to have at least 2 more parameters than the 'parallel'
5086       // directive does - the lower and upper bounds of the previous schedule.
5087       assert(CD->getNumParams() >= 4 &&
5088              "Unexpected number of parameters in loop combined directive");
5089 
5090       // Set the proper type for the bounds given what we learned from the
5091       // enclosed loops.
5092       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5093       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5094 
5095       // Previous lower and upper bounds are obtained from the region
5096       // parameters.
5097       PrevLB =
5098           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5099       PrevUB =
5100           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5101     }
5102   }
5103 
5104   // Build the iteration variable and its initialization before loop.
5105   ExprResult IV;
5106   ExprResult Init, CombInit;
5107   {
5108     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5109     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5110     Expr *RHS =
5111         (isOpenMPWorksharingDirective(DKind) ||
5112          isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5113             ? LB.get()
5114             : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5115     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5116     Init = SemaRef.ActOnFinishFullExpr(Init.get());
5117 
5118     if (isOpenMPLoopBoundSharingDirective(DKind)) {
5119       Expr *CombRHS =
5120           (isOpenMPWorksharingDirective(DKind) ||
5121            isOpenMPTaskLoopDirective(DKind) ||
5122            isOpenMPDistributeDirective(DKind))
5123               ? CombLB.get()
5124               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5125       CombInit =
5126           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5127       CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
5128     }
5129   }
5130 
5131   // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5132   SourceLocation CondLoc = AStmt->getLocStart();
5133   ExprResult Cond =
5134       (isOpenMPWorksharingDirective(DKind) ||
5135        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5136           ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5137           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5138                                NumIterations.get());
5139   ExprResult CombCond;
5140   if (isOpenMPLoopBoundSharingDirective(DKind)) {
5141     CombCond =
5142         SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
5143   }
5144   // Loop increment (IV = IV + 1)
5145   SourceLocation IncLoc = AStmt->getLocStart();
5146   ExprResult Inc =
5147       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5148                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5149   if (!Inc.isUsable())
5150     return 0;
5151   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5152   Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
5153   if (!Inc.isUsable())
5154     return 0;
5155 
5156   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5157   // Used for directives with static scheduling.
5158   // In combined construct, add combined version that use CombLB and CombUB
5159   // base variables for the update
5160   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5161   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5162       isOpenMPDistributeDirective(DKind)) {
5163     // LB + ST
5164     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5165     if (!NextLB.isUsable())
5166       return 0;
5167     // LB = LB + ST
5168     NextLB =
5169         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5170     NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
5171     if (!NextLB.isUsable())
5172       return 0;
5173     // UB + ST
5174     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5175     if (!NextUB.isUsable())
5176       return 0;
5177     // UB = UB + ST
5178     NextUB =
5179         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5180     NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
5181     if (!NextUB.isUsable())
5182       return 0;
5183     if (isOpenMPLoopBoundSharingDirective(DKind)) {
5184       CombNextLB =
5185           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
5186       if (!NextLB.isUsable())
5187         return 0;
5188       // LB = LB + ST
5189       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
5190                                       CombNextLB.get());
5191       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
5192       if (!CombNextLB.isUsable())
5193         return 0;
5194       // UB + ST
5195       CombNextUB =
5196           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
5197       if (!CombNextUB.isUsable())
5198         return 0;
5199       // UB = UB + ST
5200       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
5201                                       CombNextUB.get());
5202       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
5203       if (!CombNextUB.isUsable())
5204         return 0;
5205     }
5206   }
5207 
5208   // Create increment expression for distribute loop when combined in a same
5209   // directive with for as IV = IV + ST; ensure upper bound expression based
5210   // on PrevUB instead of NumIterations - used to implement 'for' when found
5211   // in combination with 'distribute', like in 'distribute parallel for'
5212   SourceLocation DistIncLoc = AStmt->getLocStart();
5213   ExprResult DistCond, DistInc, PrevEUB;
5214   if (isOpenMPLoopBoundSharingDirective(DKind)) {
5215     DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
5216     assert(DistCond.isUsable() && "distribute cond expr was not built");
5217 
5218     DistInc =
5219         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
5220     assert(DistInc.isUsable() && "distribute inc expr was not built");
5221     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5222                                  DistInc.get());
5223     DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
5224     assert(DistInc.isUsable() && "distribute inc expr was not built");
5225 
5226     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5227     // construct
5228     SourceLocation DistEUBLoc = AStmt->getLocStart();
5229     ExprResult IsUBGreater =
5230         SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
5231     ExprResult CondOp = SemaRef.ActOnConditionalOp(
5232         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
5233     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
5234                                  CondOp.get());
5235     PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
5236   }
5237 
5238   // Build updates and final values of the loop counters.
5239   bool HasErrors = false;
5240   Built.Counters.resize(NestedLoopCount);
5241   Built.Inits.resize(NestedLoopCount);
5242   Built.Updates.resize(NestedLoopCount);
5243   Built.Finals.resize(NestedLoopCount);
5244   {
5245     ExprResult Div;
5246     // Go from inner nested loop to outer.
5247     for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5248       LoopIterationSpace &IS = IterSpaces[Cnt];
5249       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5250       // Build: Iter = (IV / Div) % IS.NumIters
5251       // where Div is product of previous iterations' IS.NumIters.
5252       ExprResult Iter;
5253       if (Div.isUsable()) {
5254         Iter =
5255             SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
5256       } else {
5257         Iter = IV;
5258         assert((Cnt == (int)NestedLoopCount - 1) &&
5259                "unusable div expected on first iteration only");
5260       }
5261 
5262       if (Cnt != 0 && Iter.isUsable())
5263         Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
5264                                   IS.NumIterations);
5265       if (!Iter.isUsable()) {
5266         HasErrors = true;
5267         break;
5268       }
5269 
5270       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5271       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5272       DeclRefExpr *CounterVar = buildDeclRefExpr(
5273           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5274           /*RefersToCapture=*/true);
5275       ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5276                                          IS.CounterInit, Captures);
5277       if (!Init.isUsable()) {
5278         HasErrors = true;
5279         break;
5280       }
5281       ExprResult Update = buildCounterUpdate(
5282           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5283           IS.CounterStep, IS.Subtract, &Captures);
5284       if (!Update.isUsable()) {
5285         HasErrors = true;
5286         break;
5287       }
5288 
5289       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5290       ExprResult Final = buildCounterUpdate(
5291           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5292           IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5293       if (!Final.isUsable()) {
5294         HasErrors = true;
5295         break;
5296       }
5297 
5298       // Build Div for the next iteration: Div <- Div * IS.NumIters
5299       if (Cnt != 0) {
5300         if (Div.isUnset())
5301           Div = IS.NumIterations;
5302         else
5303           Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
5304                                    IS.NumIterations);
5305 
5306         // Add parentheses (for debugging purposes only).
5307         if (Div.isUsable())
5308           Div = tryBuildCapture(SemaRef, Div.get(), Captures);
5309         if (!Div.isUsable()) {
5310           HasErrors = true;
5311           break;
5312         }
5313       }
5314       if (!Update.isUsable() || !Final.isUsable()) {
5315         HasErrors = true;
5316         break;
5317       }
5318       // Save results
5319       Built.Counters[Cnt] = IS.CounterVar;
5320       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5321       Built.Inits[Cnt] = Init.get();
5322       Built.Updates[Cnt] = Update.get();
5323       Built.Finals[Cnt] = Final.get();
5324     }
5325   }
5326 
5327   if (HasErrors)
5328     return 0;
5329 
5330   // Save results
5331   Built.IterationVarRef = IV.get();
5332   Built.LastIteration = LastIteration.get();
5333   Built.NumIterations = NumIterations.get();
5334   Built.CalcLastIteration =
5335       SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5336   Built.PreCond = PreCond.get();
5337   Built.PreInits = buildPreInits(C, Captures);
5338   Built.Cond = Cond.get();
5339   Built.Init = Init.get();
5340   Built.Inc = Inc.get();
5341   Built.LB = LB.get();
5342   Built.UB = UB.get();
5343   Built.IL = IL.get();
5344   Built.ST = ST.get();
5345   Built.EUB = EUB.get();
5346   Built.NLB = NextLB.get();
5347   Built.NUB = NextUB.get();
5348   Built.PrevLB = PrevLB.get();
5349   Built.PrevUB = PrevUB.get();
5350   Built.DistInc = DistInc.get();
5351   Built.PrevEUB = PrevEUB.get();
5352   Built.DistCombinedFields.LB = CombLB.get();
5353   Built.DistCombinedFields.UB = CombUB.get();
5354   Built.DistCombinedFields.EUB = CombEUB.get();
5355   Built.DistCombinedFields.Init = CombInit.get();
5356   Built.DistCombinedFields.Cond = CombCond.get();
5357   Built.DistCombinedFields.NLB = CombNextLB.get();
5358   Built.DistCombinedFields.NUB = CombNextUB.get();
5359 
5360   return NestedLoopCount;
5361 }
5362 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)5363 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5364   auto CollapseClauses =
5365       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5366   if (CollapseClauses.begin() != CollapseClauses.end())
5367     return (*CollapseClauses.begin())->getNumForLoops();
5368   return nullptr;
5369 }
5370 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)5371 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5372   auto OrderedClauses =
5373       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5374   if (OrderedClauses.begin() != OrderedClauses.end())
5375     return (*OrderedClauses.begin())->getNumForLoops();
5376   return nullptr;
5377 }
5378 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)5379 static bool checkSimdlenSafelenSpecified(Sema &S,
5380                                          const ArrayRef<OMPClause *> Clauses) {
5381   const OMPSafelenClause *Safelen = nullptr;
5382   const OMPSimdlenClause *Simdlen = nullptr;
5383 
5384   for (const OMPClause *Clause : Clauses) {
5385     if (Clause->getClauseKind() == OMPC_safelen)
5386       Safelen = cast<OMPSafelenClause>(Clause);
5387     else if (Clause->getClauseKind() == OMPC_simdlen)
5388       Simdlen = cast<OMPSimdlenClause>(Clause);
5389     if (Safelen && Simdlen)
5390       break;
5391   }
5392 
5393   if (Simdlen && Safelen) {
5394     llvm::APSInt SimdlenRes, SafelenRes;
5395     const Expr *SimdlenLength = Simdlen->getSimdlen();
5396     const Expr *SafelenLength = Safelen->getSafelen();
5397     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5398         SimdlenLength->isInstantiationDependent() ||
5399         SimdlenLength->containsUnexpandedParameterPack())
5400       return false;
5401     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5402         SafelenLength->isInstantiationDependent() ||
5403         SafelenLength->containsUnexpandedParameterPack())
5404       return false;
5405     SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5406     SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5407     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5408     // If both simdlen and safelen clauses are specified, the value of the
5409     // simdlen parameter must be less than or equal to the value of the safelen
5410     // parameter.
5411     if (SimdlenRes > SafelenRes) {
5412       S.Diag(SimdlenLength->getExprLoc(),
5413              diag::err_omp_wrong_simdlen_safelen_values)
5414           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5415       return true;
5416     }
5417   }
5418   return false;
5419 }
5420 
5421 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5422 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
5423                                SourceLocation StartLoc, SourceLocation EndLoc,
5424                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5425   if (!AStmt)
5426     return StmtError();
5427 
5428   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5429   OMPLoopDirective::HelperExprs B;
5430   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5431   // define the nested loops number.
5432   unsigned NestedLoopCount = checkOpenMPLoop(
5433       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5434       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5435   if (NestedLoopCount == 0)
5436     return StmtError();
5437 
5438   assert((CurContext->isDependentContext() || B.builtAll()) &&
5439          "omp simd loop exprs were not built");
5440 
5441   if (!CurContext->isDependentContext()) {
5442     // Finalize the clauses that need pre-built expressions for CodeGen.
5443     for (OMPClause *C : Clauses) {
5444       if (auto *LC = dyn_cast<OMPLinearClause>(C))
5445         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5446                                      B.NumIterations, *this, CurScope,
5447                                      DSAStack))
5448           return StmtError();
5449     }
5450   }
5451 
5452   if (checkSimdlenSafelenSpecified(*this, Clauses))
5453     return StmtError();
5454 
5455   setFunctionHasBranchProtectedScope();
5456   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5457                                   Clauses, AStmt, B);
5458 }
5459 
5460 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5461 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
5462                               SourceLocation StartLoc, SourceLocation EndLoc,
5463                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5464   if (!AStmt)
5465     return StmtError();
5466 
5467   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5468   OMPLoopDirective::HelperExprs B;
5469   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5470   // define the nested loops number.
5471   unsigned NestedLoopCount = checkOpenMPLoop(
5472       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5473       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5474   if (NestedLoopCount == 0)
5475     return StmtError();
5476 
5477   assert((CurContext->isDependentContext() || B.builtAll()) &&
5478          "omp for loop exprs were not built");
5479 
5480   if (!CurContext->isDependentContext()) {
5481     // Finalize the clauses that need pre-built expressions for CodeGen.
5482     for (OMPClause *C : Clauses) {
5483       if (auto *LC = dyn_cast<OMPLinearClause>(C))
5484         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5485                                      B.NumIterations, *this, CurScope,
5486                                      DSAStack))
5487           return StmtError();
5488     }
5489   }
5490 
5491   setFunctionHasBranchProtectedScope();
5492   return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5493                                  Clauses, AStmt, B, DSAStack->isCancelRegion());
5494 }
5495 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5496 StmtResult Sema::ActOnOpenMPForSimdDirective(
5497     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5498     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5499   if (!AStmt)
5500     return StmtError();
5501 
5502   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5503   OMPLoopDirective::HelperExprs B;
5504   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5505   // define the nested loops number.
5506   unsigned NestedLoopCount =
5507       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5508                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5509                       VarsWithImplicitDSA, B);
5510   if (NestedLoopCount == 0)
5511     return StmtError();
5512 
5513   assert((CurContext->isDependentContext() || B.builtAll()) &&
5514          "omp for simd loop exprs were not built");
5515 
5516   if (!CurContext->isDependentContext()) {
5517     // Finalize the clauses that need pre-built expressions for CodeGen.
5518     for (OMPClause *C : Clauses) {
5519       if (auto *LC = dyn_cast<OMPLinearClause>(C))
5520         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5521                                      B.NumIterations, *this, CurScope,
5522                                      DSAStack))
5523           return StmtError();
5524     }
5525   }
5526 
5527   if (checkSimdlenSafelenSpecified(*this, Clauses))
5528     return StmtError();
5529 
5530   setFunctionHasBranchProtectedScope();
5531   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5532                                      Clauses, AStmt, B);
5533 }
5534 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5535 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5536                                               Stmt *AStmt,
5537                                               SourceLocation StartLoc,
5538                                               SourceLocation EndLoc) {
5539   if (!AStmt)
5540     return StmtError();
5541 
5542   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5543   auto BaseStmt = AStmt;
5544   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5545     BaseStmt = CS->getCapturedStmt();
5546   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5547     auto S = C->children();
5548     if (S.begin() == S.end())
5549       return StmtError();
5550     // All associated statements must be '#pragma omp section' except for
5551     // the first one.
5552     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5553       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5554         if (SectionStmt)
5555           Diag(SectionStmt->getLocStart(),
5556                diag::err_omp_sections_substmt_not_section);
5557         return StmtError();
5558       }
5559       cast<OMPSectionDirective>(SectionStmt)
5560           ->setHasCancel(DSAStack->isCancelRegion());
5561     }
5562   } else {
5563     Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5564     return StmtError();
5565   }
5566 
5567   setFunctionHasBranchProtectedScope();
5568 
5569   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5570                                       DSAStack->isCancelRegion());
5571 }
5572 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5573 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5574                                              SourceLocation StartLoc,
5575                                              SourceLocation EndLoc) {
5576   if (!AStmt)
5577     return StmtError();
5578 
5579   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5580 
5581   setFunctionHasBranchProtectedScope();
5582   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5583 
5584   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5585                                      DSAStack->isCancelRegion());
5586 }
5587 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5588 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5589                                             Stmt *AStmt,
5590                                             SourceLocation StartLoc,
5591                                             SourceLocation EndLoc) {
5592   if (!AStmt)
5593     return StmtError();
5594 
5595   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5596 
5597   setFunctionHasBranchProtectedScope();
5598 
5599   // OpenMP [2.7.3, single Construct, Restrictions]
5600   // The copyprivate clause must not be used with the nowait clause.
5601   const OMPClause *Nowait = nullptr;
5602   const OMPClause *Copyprivate = nullptr;
5603   for (const OMPClause *Clause : Clauses) {
5604     if (Clause->getClauseKind() == OMPC_nowait)
5605       Nowait = Clause;
5606     else if (Clause->getClauseKind() == OMPC_copyprivate)
5607       Copyprivate = Clause;
5608     if (Copyprivate && Nowait) {
5609       Diag(Copyprivate->getLocStart(),
5610            diag::err_omp_single_copyprivate_with_nowait);
5611       Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5612       return StmtError();
5613     }
5614   }
5615 
5616   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5617 }
5618 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5619 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5620                                             SourceLocation StartLoc,
5621                                             SourceLocation EndLoc) {
5622   if (!AStmt)
5623     return StmtError();
5624 
5625   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5626 
5627   setFunctionHasBranchProtectedScope();
5628 
5629   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5630 }
5631 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5632 StmtResult Sema::ActOnOpenMPCriticalDirective(
5633     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5634     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5635   if (!AStmt)
5636     return StmtError();
5637 
5638   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5639 
5640   bool ErrorFound = false;
5641   llvm::APSInt Hint;
5642   SourceLocation HintLoc;
5643   bool DependentHint = false;
5644   for (const OMPClause *C : Clauses) {
5645     if (C->getClauseKind() == OMPC_hint) {
5646       if (!DirName.getName()) {
5647         Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5648         ErrorFound = true;
5649       }
5650       Expr *E = cast<OMPHintClause>(C)->getHint();
5651       if (E->isTypeDependent() || E->isValueDependent() ||
5652           E->isInstantiationDependent()) {
5653         DependentHint = true;
5654       } else {
5655         Hint = E->EvaluateKnownConstInt(Context);
5656         HintLoc = C->getLocStart();
5657       }
5658     }
5659   }
5660   if (ErrorFound)
5661     return StmtError();
5662   const auto Pair = DSAStack->getCriticalWithHint(DirName);
5663   if (Pair.first && DirName.getName() && !DependentHint) {
5664     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5665       Diag(StartLoc, diag::err_omp_critical_with_hint);
5666       if (HintLoc.isValid())
5667         Diag(HintLoc, diag::note_omp_critical_hint_here)
5668             << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5669       else
5670         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5671       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5672         Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5673             << 1
5674             << C->getHint()->EvaluateKnownConstInt(Context).toString(
5675                    /*Radix=*/10, /*Signed=*/false);
5676       } else {
5677         Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5678       }
5679     }
5680   }
5681 
5682   setFunctionHasBranchProtectedScope();
5683 
5684   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5685                                            Clauses, AStmt);
5686   if (!Pair.first && DirName.getName() && !DependentHint)
5687     DSAStack->addCriticalWithHint(Dir, Hint);
5688   return Dir;
5689 }
5690 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5691 StmtResult Sema::ActOnOpenMPParallelForDirective(
5692     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5693     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5694   if (!AStmt)
5695     return StmtError();
5696 
5697   auto *CS = cast<CapturedStmt>(AStmt);
5698   // 1.2.2 OpenMP Language Terminology
5699   // Structured block - An executable statement with a single entry at the
5700   // top and a single exit at the bottom.
5701   // The point of exit cannot be a branch out of the structured block.
5702   // longjmp() and throw() must not violate the entry/exit criteria.
5703   CS->getCapturedDecl()->setNothrow();
5704 
5705   OMPLoopDirective::HelperExprs B;
5706   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5707   // define the nested loops number.
5708   unsigned NestedLoopCount =
5709       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5710                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5711                       VarsWithImplicitDSA, B);
5712   if (NestedLoopCount == 0)
5713     return StmtError();
5714 
5715   assert((CurContext->isDependentContext() || B.builtAll()) &&
5716          "omp parallel for loop exprs were not built");
5717 
5718   if (!CurContext->isDependentContext()) {
5719     // Finalize the clauses that need pre-built expressions for CodeGen.
5720     for (OMPClause *C : Clauses) {
5721       if (auto *LC = dyn_cast<OMPLinearClause>(C))
5722         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5723                                      B.NumIterations, *this, CurScope,
5724                                      DSAStack))
5725           return StmtError();
5726     }
5727   }
5728 
5729   setFunctionHasBranchProtectedScope();
5730   return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5731                                          NestedLoopCount, Clauses, AStmt, B,
5732                                          DSAStack->isCancelRegion());
5733 }
5734 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)5735 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
5736     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5737     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5738   if (!AStmt)
5739     return StmtError();
5740 
5741   auto *CS = cast<CapturedStmt>(AStmt);
5742   // 1.2.2 OpenMP Language Terminology
5743   // Structured block - An executable statement with a single entry at the
5744   // top and a single exit at the bottom.
5745   // The point of exit cannot be a branch out of the structured block.
5746   // longjmp() and throw() must not violate the entry/exit criteria.
5747   CS->getCapturedDecl()->setNothrow();
5748 
5749   OMPLoopDirective::HelperExprs B;
5750   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5751   // define the nested loops number.
5752   unsigned NestedLoopCount =
5753       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5754                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5755                       VarsWithImplicitDSA, B);
5756   if (NestedLoopCount == 0)
5757     return StmtError();
5758 
5759   if (!CurContext->isDependentContext()) {
5760     // Finalize the clauses that need pre-built expressions for CodeGen.
5761     for (OMPClause *C : Clauses) {
5762       if (auto *LC = dyn_cast<OMPLinearClause>(C))
5763         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5764                                      B.NumIterations, *this, CurScope,
5765                                      DSAStack))
5766           return StmtError();
5767     }
5768   }
5769 
5770   if (checkSimdlenSafelenSpecified(*this, Clauses))
5771     return StmtError();
5772 
5773   setFunctionHasBranchProtectedScope();
5774   return OMPParallelForSimdDirective::Create(
5775       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5776 }
5777 
5778 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5779 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
5780                                            Stmt *AStmt, SourceLocation StartLoc,
5781                                            SourceLocation EndLoc) {
5782   if (!AStmt)
5783     return StmtError();
5784 
5785   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5786   auto BaseStmt = AStmt;
5787   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5788     BaseStmt = CS->getCapturedStmt();
5789   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5790     auto S = C->children();
5791     if (S.begin() == S.end())
5792       return StmtError();
5793     // All associated statements must be '#pragma omp section' except for
5794     // the first one.
5795     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5796       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5797         if (SectionStmt)
5798           Diag(SectionStmt->getLocStart(),
5799                diag::err_omp_parallel_sections_substmt_not_section);
5800         return StmtError();
5801       }
5802       cast<OMPSectionDirective>(SectionStmt)
5803           ->setHasCancel(DSAStack->isCancelRegion());
5804     }
5805   } else {
5806     Diag(AStmt->getLocStart(),
5807          diag::err_omp_parallel_sections_not_compound_stmt);
5808     return StmtError();
5809   }
5810 
5811   setFunctionHasBranchProtectedScope();
5812 
5813   return OMPParallelSectionsDirective::Create(
5814       Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5815 }
5816 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5817 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
5818                                           Stmt *AStmt, SourceLocation StartLoc,
5819                                           SourceLocation EndLoc) {
5820   if (!AStmt)
5821     return StmtError();
5822 
5823   auto *CS = cast<CapturedStmt>(AStmt);
5824   // 1.2.2 OpenMP Language Terminology
5825   // Structured block - An executable statement with a single entry at the
5826   // top and a single exit at the bottom.
5827   // The point of exit cannot be a branch out of the structured block.
5828   // longjmp() and throw() must not violate the entry/exit criteria.
5829   CS->getCapturedDecl()->setNothrow();
5830 
5831   setFunctionHasBranchProtectedScope();
5832 
5833   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5834                                   DSAStack->isCancelRegion());
5835 }
5836 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)5837 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
5838                                                SourceLocation EndLoc) {
5839   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5840 }
5841 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)5842 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
5843                                              SourceLocation EndLoc) {
5844   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5845 }
5846 
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)5847 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
5848                                               SourceLocation EndLoc) {
5849   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5850 }
5851 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5852 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
5853                                                Stmt *AStmt,
5854                                                SourceLocation StartLoc,
5855                                                SourceLocation EndLoc) {
5856   if (!AStmt)
5857     return StmtError();
5858 
5859   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5860 
5861   setFunctionHasBranchProtectedScope();
5862 
5863   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5864                                        AStmt,
5865                                        DSAStack->getTaskgroupReductionRef());
5866 }
5867 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)5868 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
5869                                            SourceLocation StartLoc,
5870                                            SourceLocation EndLoc) {
5871   assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5872   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5873 }
5874 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5875 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
5876                                              Stmt *AStmt,
5877                                              SourceLocation StartLoc,
5878                                              SourceLocation EndLoc) {
5879   const OMPClause *DependFound = nullptr;
5880   const OMPClause *DependSourceClause = nullptr;
5881   const OMPClause *DependSinkClause = nullptr;
5882   bool ErrorFound = false;
5883   const OMPThreadsClause *TC = nullptr;
5884   const OMPSIMDClause *SC = nullptr;
5885   for (const OMPClause *C : Clauses) {
5886     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5887       DependFound = C;
5888       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5889         if (DependSourceClause) {
5890           Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5891               << getOpenMPDirectiveName(OMPD_ordered)
5892               << getOpenMPClauseName(OMPC_depend) << 2;
5893           ErrorFound = true;
5894         } else {
5895           DependSourceClause = C;
5896         }
5897         if (DependSinkClause) {
5898           Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5899               << 0;
5900           ErrorFound = true;
5901         }
5902       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5903         if (DependSourceClause) {
5904           Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5905               << 1;
5906           ErrorFound = true;
5907         }
5908         DependSinkClause = C;
5909       }
5910     } else if (C->getClauseKind() == OMPC_threads) {
5911       TC = cast<OMPThreadsClause>(C);
5912     } else if (C->getClauseKind() == OMPC_simd) {
5913       SC = cast<OMPSIMDClause>(C);
5914     }
5915   }
5916   if (!ErrorFound && !SC &&
5917       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5918     // OpenMP [2.8.1,simd Construct, Restrictions]
5919     // An ordered construct with the simd clause is the only OpenMP construct
5920     // that can appear in the simd region.
5921     Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5922     ErrorFound = true;
5923   } else if (DependFound && (TC || SC)) {
5924     Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5925         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5926     ErrorFound = true;
5927   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
5928     Diag(DependFound->getLocStart(),
5929          diag::err_omp_ordered_directive_without_param);
5930     ErrorFound = true;
5931   } else if (TC || Clauses.empty()) {
5932     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
5933       SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5934       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5935           << (TC != nullptr);
5936       Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5937       ErrorFound = true;
5938     }
5939   }
5940   if ((!AStmt && !DependFound) || ErrorFound)
5941     return StmtError();
5942 
5943   if (AStmt) {
5944     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5945 
5946     setFunctionHasBranchProtectedScope();
5947   }
5948 
5949   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5950 }
5951 
5952 namespace {
5953 /// Helper class for checking expression in 'omp atomic [update]'
5954 /// construct.
5955 class OpenMPAtomicUpdateChecker {
5956   /// Error results for atomic update expressions.
5957   enum ExprAnalysisErrorCode {
5958     /// A statement is not an expression statement.
5959     NotAnExpression,
5960     /// Expression is not builtin binary or unary operation.
5961     NotABinaryOrUnaryExpression,
5962     /// Unary operation is not post-/pre- increment/decrement operation.
5963     NotAnUnaryIncDecExpression,
5964     /// An expression is not of scalar type.
5965     NotAScalarType,
5966     /// A binary operation is not an assignment operation.
5967     NotAnAssignmentOp,
5968     /// RHS part of the binary operation is not a binary expression.
5969     NotABinaryExpression,
5970     /// RHS part is not additive/multiplicative/shift/biwise binary
5971     /// expression.
5972     NotABinaryOperator,
5973     /// RHS binary operation does not have reference to the updated LHS
5974     /// part.
5975     NotAnUpdateExpression,
5976     /// No errors is found.
5977     NoError
5978   };
5979   /// Reference to Sema.
5980   Sema &SemaRef;
5981   /// A location for note diagnostics (when error is found).
5982   SourceLocation NoteLoc;
5983   /// 'x' lvalue part of the source atomic expression.
5984   Expr *X;
5985   /// 'expr' rvalue part of the source atomic expression.
5986   Expr *E;
5987   /// Helper expression of the form
5988   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5989   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5990   Expr *UpdateExpr;
5991   /// Is 'x' a LHS in a RHS part of full update expression. It is
5992   /// important for non-associative operations.
5993   bool IsXLHSInRHSPart;
5994   BinaryOperatorKind Op;
5995   SourceLocation OpLoc;
5996   /// true if the source expression is a postfix unary operation, false
5997   /// if it is a prefix unary operation.
5998   bool IsPostfixUpdate;
5999 
6000 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)6001   OpenMPAtomicUpdateChecker(Sema &SemaRef)
6002       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6003         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6004   /// Check specified statement that it is suitable for 'atomic update'
6005   /// constructs and extract 'x', 'expr' and Operation from the original
6006   /// expression. If DiagId and NoteId == 0, then only check is performed
6007   /// without error notification.
6008   /// \param DiagId Diagnostic which should be emitted if error is found.
6009   /// \param NoteId Diagnostic note for the main error message.
6010   /// \return true if statement is not an update expression, false otherwise.
6011   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
6012   /// Return the 'x' lvalue part of the source atomic expression.
getX() const6013   Expr *getX() const { return X; }
6014   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const6015   Expr *getExpr() const { return E; }
6016   /// Return the update expression used in calculation of the updated
6017   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6018   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const6019   Expr *getUpdateExpr() const { return UpdateExpr; }
6020   /// Return true if 'x' is LHS in RHS part of full update expression,
6021   /// false otherwise.
isXLHSInRHSPart() const6022   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6023 
6024   /// true if the source expression is a postfix unary operation, false
6025   /// if it is a prefix unary operation.
isPostfixUpdate() const6026   bool isPostfixUpdate() const { return IsPostfixUpdate; }
6027 
6028 private:
6029   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
6030                             unsigned NoteId = 0);
6031 };
6032 } // namespace
6033 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)6034 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6035     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
6036   ExprAnalysisErrorCode ErrorFound = NoError;
6037   SourceLocation ErrorLoc, NoteLoc;
6038   SourceRange ErrorRange, NoteRange;
6039   // Allowed constructs are:
6040   //  x = x binop expr;
6041   //  x = expr binop x;
6042   if (AtomicBinOp->getOpcode() == BO_Assign) {
6043     X = AtomicBinOp->getLHS();
6044     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6045             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6046       if (AtomicInnerBinOp->isMultiplicativeOp() ||
6047           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6048           AtomicInnerBinOp->isBitwiseOp()) {
6049         Op = AtomicInnerBinOp->getOpcode();
6050         OpLoc = AtomicInnerBinOp->getOperatorLoc();
6051         Expr *LHS = AtomicInnerBinOp->getLHS();
6052         Expr *RHS = AtomicInnerBinOp->getRHS();
6053         llvm::FoldingSetNodeID XId, LHSId, RHSId;
6054         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6055                                           /*Canonical=*/true);
6056         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6057                                             /*Canonical=*/true);
6058         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6059                                             /*Canonical=*/true);
6060         if (XId == LHSId) {
6061           E = RHS;
6062           IsXLHSInRHSPart = true;
6063         } else if (XId == RHSId) {
6064           E = LHS;
6065           IsXLHSInRHSPart = false;
6066         } else {
6067           ErrorLoc = AtomicInnerBinOp->getExprLoc();
6068           ErrorRange = AtomicInnerBinOp->getSourceRange();
6069           NoteLoc = X->getExprLoc();
6070           NoteRange = X->getSourceRange();
6071           ErrorFound = NotAnUpdateExpression;
6072         }
6073       } else {
6074         ErrorLoc = AtomicInnerBinOp->getExprLoc();
6075         ErrorRange = AtomicInnerBinOp->getSourceRange();
6076         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6077         NoteRange = SourceRange(NoteLoc, NoteLoc);
6078         ErrorFound = NotABinaryOperator;
6079       }
6080     } else {
6081       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6082       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6083       ErrorFound = NotABinaryExpression;
6084     }
6085   } else {
6086     ErrorLoc = AtomicBinOp->getExprLoc();
6087     ErrorRange = AtomicBinOp->getSourceRange();
6088     NoteLoc = AtomicBinOp->getOperatorLoc();
6089     NoteRange = SourceRange(NoteLoc, NoteLoc);
6090     ErrorFound = NotAnAssignmentOp;
6091   }
6092   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6093     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6094     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6095     return true;
6096   }
6097   if (SemaRef.CurContext->isDependentContext())
6098     E = X = UpdateExpr = nullptr;
6099   return ErrorFound != NoError;
6100 }
6101 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)6102 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
6103                                                unsigned NoteId) {
6104   ExprAnalysisErrorCode ErrorFound = NoError;
6105   SourceLocation ErrorLoc, NoteLoc;
6106   SourceRange ErrorRange, NoteRange;
6107   // Allowed constructs are:
6108   //  x++;
6109   //  x--;
6110   //  ++x;
6111   //  --x;
6112   //  x binop= expr;
6113   //  x = x binop expr;
6114   //  x = expr binop x;
6115   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6116     AtomicBody = AtomicBody->IgnoreParenImpCasts();
6117     if (AtomicBody->getType()->isScalarType() ||
6118         AtomicBody->isInstantiationDependent()) {
6119       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6120               AtomicBody->IgnoreParenImpCasts())) {
6121         // Check for Compound Assignment Operation
6122         Op = BinaryOperator::getOpForCompoundAssignment(
6123             AtomicCompAssignOp->getOpcode());
6124         OpLoc = AtomicCompAssignOp->getOperatorLoc();
6125         E = AtomicCompAssignOp->getRHS();
6126         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6127         IsXLHSInRHSPart = true;
6128       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6129                      AtomicBody->IgnoreParenImpCasts())) {
6130         // Check for Binary Operation
6131         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6132           return true;
6133       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6134                      AtomicBody->IgnoreParenImpCasts())) {
6135         // Check for Unary Operation
6136         if (AtomicUnaryOp->isIncrementDecrementOp()) {
6137           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6138           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6139           OpLoc = AtomicUnaryOp->getOperatorLoc();
6140           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6141           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
6142           IsXLHSInRHSPart = true;
6143         } else {
6144           ErrorFound = NotAnUnaryIncDecExpression;
6145           ErrorLoc = AtomicUnaryOp->getExprLoc();
6146           ErrorRange = AtomicUnaryOp->getSourceRange();
6147           NoteLoc = AtomicUnaryOp->getOperatorLoc();
6148           NoteRange = SourceRange(NoteLoc, NoteLoc);
6149         }
6150       } else if (!AtomicBody->isInstantiationDependent()) {
6151         ErrorFound = NotABinaryOrUnaryExpression;
6152         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6153         NoteRange = ErrorRange = AtomicBody->getSourceRange();
6154       }
6155     } else {
6156       ErrorFound = NotAScalarType;
6157       NoteLoc = ErrorLoc = AtomicBody->getLocStart();
6158       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6159     }
6160   } else {
6161     ErrorFound = NotAnExpression;
6162     NoteLoc = ErrorLoc = S->getLocStart();
6163     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6164   }
6165   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6166     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6167     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6168     return true;
6169   }
6170   if (SemaRef.CurContext->isDependentContext())
6171     E = X = UpdateExpr = nullptr;
6172   if (ErrorFound == NoError && E && X) {
6173     // Build an update expression of form 'OpaqueValueExpr(x) binop
6174     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6175     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6176     auto *OVEX = new (SemaRef.getASTContext())
6177         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6178     auto *OVEExpr = new (SemaRef.getASTContext())
6179         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
6180     ExprResult Update =
6181         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
6182                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
6183     if (Update.isInvalid())
6184       return true;
6185     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6186                                                Sema::AA_Casting);
6187     if (Update.isInvalid())
6188       return true;
6189     UpdateExpr = Update.get();
6190   }
6191   return ErrorFound != NoError;
6192 }
6193 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6194 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
6195                                             Stmt *AStmt,
6196                                             SourceLocation StartLoc,
6197                                             SourceLocation EndLoc) {
6198   if (!AStmt)
6199     return StmtError();
6200 
6201   auto *CS = cast<CapturedStmt>(AStmt);
6202   // 1.2.2 OpenMP Language Terminology
6203   // Structured block - An executable statement with a single entry at the
6204   // top and a single exit at the bottom.
6205   // The point of exit cannot be a branch out of the structured block.
6206   // longjmp() and throw() must not violate the entry/exit criteria.
6207   OpenMPClauseKind AtomicKind = OMPC_unknown;
6208   SourceLocation AtomicKindLoc;
6209   for (const OMPClause *C : Clauses) {
6210     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6211         C->getClauseKind() == OMPC_update ||
6212         C->getClauseKind() == OMPC_capture) {
6213       if (AtomicKind != OMPC_unknown) {
6214         Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
6215             << SourceRange(C->getLocStart(), C->getLocEnd());
6216         Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6217             << getOpenMPClauseName(AtomicKind);
6218       } else {
6219         AtomicKind = C->getClauseKind();
6220         AtomicKindLoc = C->getLocStart();
6221       }
6222     }
6223   }
6224 
6225   Stmt *Body = CS->getCapturedStmt();
6226   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6227     Body = EWC->getSubExpr();
6228 
6229   Expr *X = nullptr;
6230   Expr *V = nullptr;
6231   Expr *E = nullptr;
6232   Expr *UE = nullptr;
6233   bool IsXLHSInRHSPart = false;
6234   bool IsPostfixUpdate = false;
6235   // OpenMP [2.12.6, atomic Construct]
6236   // In the next expressions:
6237   // * x and v (as applicable) are both l-value expressions with scalar type.
6238   // * During the execution of an atomic region, multiple syntactic
6239   // occurrences of x must designate the same storage location.
6240   // * Neither of v and expr (as applicable) may access the storage location
6241   // designated by x.
6242   // * Neither of x and expr (as applicable) may access the storage location
6243   // designated by v.
6244   // * expr is an expression with scalar type.
6245   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6246   // * binop, binop=, ++, and -- are not overloaded operators.
6247   // * The expression x binop expr must be numerically equivalent to x binop
6248   // (expr). This requirement is satisfied if the operators in expr have
6249   // precedence greater than binop, or by using parentheses around expr or
6250   // subexpressions of expr.
6251   // * The expression expr binop x must be numerically equivalent to (expr)
6252   // binop x. This requirement is satisfied if the operators in expr have
6253   // precedence equal to or greater than binop, or by using parentheses around
6254   // expr or subexpressions of expr.
6255   // * For forms that allow multiple occurrences of x, the number of times
6256   // that x is evaluated is unspecified.
6257   if (AtomicKind == OMPC_read) {
6258     enum {
6259       NotAnExpression,
6260       NotAnAssignmentOp,
6261       NotAScalarType,
6262       NotAnLValue,
6263       NoError
6264     } ErrorFound = NoError;
6265     SourceLocation ErrorLoc, NoteLoc;
6266     SourceRange ErrorRange, NoteRange;
6267     // If clause is read:
6268     //  v = x;
6269     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6270       const auto *AtomicBinOp =
6271           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6272       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6273         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6274         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6275         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6276             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6277           if (!X->isLValue() || !V->isLValue()) {
6278             const Expr *NotLValueExpr = X->isLValue() ? V : X;
6279             ErrorFound = NotAnLValue;
6280             ErrorLoc = AtomicBinOp->getExprLoc();
6281             ErrorRange = AtomicBinOp->getSourceRange();
6282             NoteLoc = NotLValueExpr->getExprLoc();
6283             NoteRange = NotLValueExpr->getSourceRange();
6284           }
6285         } else if (!X->isInstantiationDependent() ||
6286                    !V->isInstantiationDependent()) {
6287           const Expr *NotScalarExpr =
6288               (X->isInstantiationDependent() || X->getType()->isScalarType())
6289                   ? V
6290                   : X;
6291           ErrorFound = NotAScalarType;
6292           ErrorLoc = AtomicBinOp->getExprLoc();
6293           ErrorRange = AtomicBinOp->getSourceRange();
6294           NoteLoc = NotScalarExpr->getExprLoc();
6295           NoteRange = NotScalarExpr->getSourceRange();
6296         }
6297       } else if (!AtomicBody->isInstantiationDependent()) {
6298         ErrorFound = NotAnAssignmentOp;
6299         ErrorLoc = AtomicBody->getExprLoc();
6300         ErrorRange = AtomicBody->getSourceRange();
6301         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6302                               : AtomicBody->getExprLoc();
6303         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6304                                 : AtomicBody->getSourceRange();
6305       }
6306     } else {
6307       ErrorFound = NotAnExpression;
6308       NoteLoc = ErrorLoc = Body->getLocStart();
6309       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6310     }
6311     if (ErrorFound != NoError) {
6312       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6313           << ErrorRange;
6314       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6315                                                       << NoteRange;
6316       return StmtError();
6317     }
6318     if (CurContext->isDependentContext())
6319       V = X = nullptr;
6320   } else if (AtomicKind == OMPC_write) {
6321     enum {
6322       NotAnExpression,
6323       NotAnAssignmentOp,
6324       NotAScalarType,
6325       NotAnLValue,
6326       NoError
6327     } ErrorFound = NoError;
6328     SourceLocation ErrorLoc, NoteLoc;
6329     SourceRange ErrorRange, NoteRange;
6330     // If clause is write:
6331     //  x = expr;
6332     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6333       const auto *AtomicBinOp =
6334           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6335       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6336         X = AtomicBinOp->getLHS();
6337         E = AtomicBinOp->getRHS();
6338         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6339             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6340           if (!X->isLValue()) {
6341             ErrorFound = NotAnLValue;
6342             ErrorLoc = AtomicBinOp->getExprLoc();
6343             ErrorRange = AtomicBinOp->getSourceRange();
6344             NoteLoc = X->getExprLoc();
6345             NoteRange = X->getSourceRange();
6346           }
6347         } else if (!X->isInstantiationDependent() ||
6348                    !E->isInstantiationDependent()) {
6349           const Expr *NotScalarExpr =
6350               (X->isInstantiationDependent() || X->getType()->isScalarType())
6351                   ? E
6352                   : X;
6353           ErrorFound = NotAScalarType;
6354           ErrorLoc = AtomicBinOp->getExprLoc();
6355           ErrorRange = AtomicBinOp->getSourceRange();
6356           NoteLoc = NotScalarExpr->getExprLoc();
6357           NoteRange = NotScalarExpr->getSourceRange();
6358         }
6359       } else if (!AtomicBody->isInstantiationDependent()) {
6360         ErrorFound = NotAnAssignmentOp;
6361         ErrorLoc = AtomicBody->getExprLoc();
6362         ErrorRange = AtomicBody->getSourceRange();
6363         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6364                               : AtomicBody->getExprLoc();
6365         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6366                                 : AtomicBody->getSourceRange();
6367       }
6368     } else {
6369       ErrorFound = NotAnExpression;
6370       NoteLoc = ErrorLoc = Body->getLocStart();
6371       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6372     }
6373     if (ErrorFound != NoError) {
6374       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6375           << ErrorRange;
6376       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6377                                                       << NoteRange;
6378       return StmtError();
6379     }
6380     if (CurContext->isDependentContext())
6381       E = X = nullptr;
6382   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6383     // If clause is update:
6384     //  x++;
6385     //  x--;
6386     //  ++x;
6387     //  --x;
6388     //  x binop= expr;
6389     //  x = x binop expr;
6390     //  x = expr binop x;
6391     OpenMPAtomicUpdateChecker Checker(*this);
6392     if (Checker.checkStatement(
6393             Body, (AtomicKind == OMPC_update)
6394                       ? diag::err_omp_atomic_update_not_expression_statement
6395                       : diag::err_omp_atomic_not_expression_statement,
6396             diag::note_omp_atomic_update))
6397       return StmtError();
6398     if (!CurContext->isDependentContext()) {
6399       E = Checker.getExpr();
6400       X = Checker.getX();
6401       UE = Checker.getUpdateExpr();
6402       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6403     }
6404   } else if (AtomicKind == OMPC_capture) {
6405     enum {
6406       NotAnAssignmentOp,
6407       NotACompoundStatement,
6408       NotTwoSubstatements,
6409       NotASpecificExpression,
6410       NoError
6411     } ErrorFound = NoError;
6412     SourceLocation ErrorLoc, NoteLoc;
6413     SourceRange ErrorRange, NoteRange;
6414     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6415       // If clause is a capture:
6416       //  v = x++;
6417       //  v = x--;
6418       //  v = ++x;
6419       //  v = --x;
6420       //  v = x binop= expr;
6421       //  v = x = x binop expr;
6422       //  v = x = expr binop x;
6423       const auto *AtomicBinOp =
6424           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6425       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6426         V = AtomicBinOp->getLHS();
6427         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6428         OpenMPAtomicUpdateChecker Checker(*this);
6429         if (Checker.checkStatement(
6430                 Body, diag::err_omp_atomic_capture_not_expression_statement,
6431                 diag::note_omp_atomic_update))
6432           return StmtError();
6433         E = Checker.getExpr();
6434         X = Checker.getX();
6435         UE = Checker.getUpdateExpr();
6436         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6437         IsPostfixUpdate = Checker.isPostfixUpdate();
6438       } else if (!AtomicBody->isInstantiationDependent()) {
6439         ErrorLoc = AtomicBody->getExprLoc();
6440         ErrorRange = AtomicBody->getSourceRange();
6441         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6442                               : AtomicBody->getExprLoc();
6443         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6444                                 : AtomicBody->getSourceRange();
6445         ErrorFound = NotAnAssignmentOp;
6446       }
6447       if (ErrorFound != NoError) {
6448         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6449             << ErrorRange;
6450         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6451         return StmtError();
6452       }
6453       if (CurContext->isDependentContext())
6454         UE = V = E = X = nullptr;
6455     } else {
6456       // If clause is a capture:
6457       //  { v = x; x = expr; }
6458       //  { v = x; x++; }
6459       //  { v = x; x--; }
6460       //  { v = x; ++x; }
6461       //  { v = x; --x; }
6462       //  { v = x; x binop= expr; }
6463       //  { v = x; x = x binop expr; }
6464       //  { v = x; x = expr binop x; }
6465       //  { x++; v = x; }
6466       //  { x--; v = x; }
6467       //  { ++x; v = x; }
6468       //  { --x; v = x; }
6469       //  { x binop= expr; v = x; }
6470       //  { x = x binop expr; v = x; }
6471       //  { x = expr binop x; v = x; }
6472       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6473         // Check that this is { expr1; expr2; }
6474         if (CS->size() == 2) {
6475           Stmt *First = CS->body_front();
6476           Stmt *Second = CS->body_back();
6477           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6478             First = EWC->getSubExpr()->IgnoreParenImpCasts();
6479           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6480             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6481           // Need to find what subexpression is 'v' and what is 'x'.
6482           OpenMPAtomicUpdateChecker Checker(*this);
6483           bool IsUpdateExprFound = !Checker.checkStatement(Second);
6484           BinaryOperator *BinOp = nullptr;
6485           if (IsUpdateExprFound) {
6486             BinOp = dyn_cast<BinaryOperator>(First);
6487             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6488           }
6489           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6490             //  { v = x; x++; }
6491             //  { v = x; x--; }
6492             //  { v = x; ++x; }
6493             //  { v = x; --x; }
6494             //  { v = x; x binop= expr; }
6495             //  { v = x; x = x binop expr; }
6496             //  { v = x; x = expr binop x; }
6497             // Check that the first expression has form v = x.
6498             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6499             llvm::FoldingSetNodeID XId, PossibleXId;
6500             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6501             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6502             IsUpdateExprFound = XId == PossibleXId;
6503             if (IsUpdateExprFound) {
6504               V = BinOp->getLHS();
6505               X = Checker.getX();
6506               E = Checker.getExpr();
6507               UE = Checker.getUpdateExpr();
6508               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6509               IsPostfixUpdate = true;
6510             }
6511           }
6512           if (!IsUpdateExprFound) {
6513             IsUpdateExprFound = !Checker.checkStatement(First);
6514             BinOp = nullptr;
6515             if (IsUpdateExprFound) {
6516               BinOp = dyn_cast<BinaryOperator>(Second);
6517               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6518             }
6519             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6520               //  { x++; v = x; }
6521               //  { x--; v = x; }
6522               //  { ++x; v = x; }
6523               //  { --x; v = x; }
6524               //  { x binop= expr; v = x; }
6525               //  { x = x binop expr; v = x; }
6526               //  { x = expr binop x; v = x; }
6527               // Check that the second expression has form v = x.
6528               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6529               llvm::FoldingSetNodeID XId, PossibleXId;
6530               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6531               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6532               IsUpdateExprFound = XId == PossibleXId;
6533               if (IsUpdateExprFound) {
6534                 V = BinOp->getLHS();
6535                 X = Checker.getX();
6536                 E = Checker.getExpr();
6537                 UE = Checker.getUpdateExpr();
6538                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6539                 IsPostfixUpdate = false;
6540               }
6541             }
6542           }
6543           if (!IsUpdateExprFound) {
6544             //  { v = x; x = expr; }
6545             auto *FirstExpr = dyn_cast<Expr>(First);
6546             auto *SecondExpr = dyn_cast<Expr>(Second);
6547             if (!FirstExpr || !SecondExpr ||
6548                 !(FirstExpr->isInstantiationDependent() ||
6549                   SecondExpr->isInstantiationDependent())) {
6550               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6551               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6552                 ErrorFound = NotAnAssignmentOp;
6553                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6554                                                 : First->getLocStart();
6555                 NoteRange = ErrorRange = FirstBinOp
6556                                              ? FirstBinOp->getSourceRange()
6557                                              : SourceRange(ErrorLoc, ErrorLoc);
6558               } else {
6559                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6560                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6561                   ErrorFound = NotAnAssignmentOp;
6562                   NoteLoc = ErrorLoc = SecondBinOp
6563                                            ? SecondBinOp->getOperatorLoc()
6564                                            : Second->getLocStart();
6565                   NoteRange = ErrorRange =
6566                       SecondBinOp ? SecondBinOp->getSourceRange()
6567                                   : SourceRange(ErrorLoc, ErrorLoc);
6568                 } else {
6569                   Expr *PossibleXRHSInFirst =
6570                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
6571                   Expr *PossibleXLHSInSecond =
6572                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
6573                   llvm::FoldingSetNodeID X1Id, X2Id;
6574                   PossibleXRHSInFirst->Profile(X1Id, Context,
6575                                                /*Canonical=*/true);
6576                   PossibleXLHSInSecond->Profile(X2Id, Context,
6577                                                 /*Canonical=*/true);
6578                   IsUpdateExprFound = X1Id == X2Id;
6579                   if (IsUpdateExprFound) {
6580                     V = FirstBinOp->getLHS();
6581                     X = SecondBinOp->getLHS();
6582                     E = SecondBinOp->getRHS();
6583                     UE = nullptr;
6584                     IsXLHSInRHSPart = false;
6585                     IsPostfixUpdate = true;
6586                   } else {
6587                     ErrorFound = NotASpecificExpression;
6588                     ErrorLoc = FirstBinOp->getExprLoc();
6589                     ErrorRange = FirstBinOp->getSourceRange();
6590                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6591                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
6592                   }
6593                 }
6594               }
6595             }
6596           }
6597         } else {
6598           NoteLoc = ErrorLoc = Body->getLocStart();
6599           NoteRange = ErrorRange =
6600               SourceRange(Body->getLocStart(), Body->getLocStart());
6601           ErrorFound = NotTwoSubstatements;
6602         }
6603       } else {
6604         NoteLoc = ErrorLoc = Body->getLocStart();
6605         NoteRange = ErrorRange =
6606             SourceRange(Body->getLocStart(), Body->getLocStart());
6607         ErrorFound = NotACompoundStatement;
6608       }
6609       if (ErrorFound != NoError) {
6610         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6611             << ErrorRange;
6612         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6613         return StmtError();
6614       }
6615       if (CurContext->isDependentContext())
6616         UE = V = E = X = nullptr;
6617     }
6618   }
6619 
6620   setFunctionHasBranchProtectedScope();
6621 
6622   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6623                                     X, V, E, UE, IsXLHSInRHSPart,
6624                                     IsPostfixUpdate);
6625 }
6626 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6627 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
6628                                             Stmt *AStmt,
6629                                             SourceLocation StartLoc,
6630                                             SourceLocation EndLoc) {
6631   if (!AStmt)
6632     return StmtError();
6633 
6634   auto *CS = cast<CapturedStmt>(AStmt);
6635   // 1.2.2 OpenMP Language Terminology
6636   // Structured block - An executable statement with a single entry at the
6637   // top and a single exit at the bottom.
6638   // The point of exit cannot be a branch out of the structured block.
6639   // longjmp() and throw() must not violate the entry/exit criteria.
6640   CS->getCapturedDecl()->setNothrow();
6641   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6642        ThisCaptureLevel > 1; --ThisCaptureLevel) {
6643     CS = cast<CapturedStmt>(CS->getCapturedStmt());
6644     // 1.2.2 OpenMP Language Terminology
6645     // Structured block - An executable statement with a single entry at the
6646     // top and a single exit at the bottom.
6647     // The point of exit cannot be a branch out of the structured block.
6648     // longjmp() and throw() must not violate the entry/exit criteria.
6649     CS->getCapturedDecl()->setNothrow();
6650   }
6651 
6652   // OpenMP [2.16, Nesting of Regions]
6653   // If specified, a teams construct must be contained within a target
6654   // construct. That target construct must contain no statements or directives
6655   // outside of the teams construct.
6656   if (DSAStack->hasInnerTeamsRegion()) {
6657     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
6658     bool OMPTeamsFound = true;
6659     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
6660       auto I = CS->body_begin();
6661       while (I != CS->body_end()) {
6662         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6663         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6664           OMPTeamsFound = false;
6665           break;
6666         }
6667         ++I;
6668       }
6669       assert(I != CS->body_end() && "Not found statement");
6670       S = *I;
6671     } else {
6672       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
6673       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6674     }
6675     if (!OMPTeamsFound) {
6676       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6677       Diag(DSAStack->getInnerTeamsRegionLoc(),
6678            diag::note_omp_nested_teams_construct_here);
6679       Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6680           << isa<OMPExecutableDirective>(S);
6681       return StmtError();
6682     }
6683   }
6684 
6685   setFunctionHasBranchProtectedScope();
6686 
6687   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6688 }
6689 
6690 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6691 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
6692                                          Stmt *AStmt, SourceLocation StartLoc,
6693                                          SourceLocation EndLoc) {
6694   if (!AStmt)
6695     return StmtError();
6696 
6697   auto *CS = cast<CapturedStmt>(AStmt);
6698   // 1.2.2 OpenMP Language Terminology
6699   // Structured block - An executable statement with a single entry at the
6700   // top and a single exit at the bottom.
6701   // The point of exit cannot be a branch out of the structured block.
6702   // longjmp() and throw() must not violate the entry/exit criteria.
6703   CS->getCapturedDecl()->setNothrow();
6704   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
6705        ThisCaptureLevel > 1; --ThisCaptureLevel) {
6706     CS = cast<CapturedStmt>(CS->getCapturedStmt());
6707     // 1.2.2 OpenMP Language Terminology
6708     // Structured block - An executable statement with a single entry at the
6709     // top and a single exit at the bottom.
6710     // The point of exit cannot be a branch out of the structured block.
6711     // longjmp() and throw() must not violate the entry/exit criteria.
6712     CS->getCapturedDecl()->setNothrow();
6713   }
6714 
6715   setFunctionHasBranchProtectedScope();
6716 
6717   return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6718                                             AStmt);
6719 }
6720 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)6721 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
6722     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6723     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6724   if (!AStmt)
6725     return StmtError();
6726 
6727   auto *CS = cast<CapturedStmt>(AStmt);
6728   // 1.2.2 OpenMP Language Terminology
6729   // Structured block - An executable statement with a single entry at the
6730   // top and a single exit at the bottom.
6731   // The point of exit cannot be a branch out of the structured block.
6732   // longjmp() and throw() must not violate the entry/exit criteria.
6733   CS->getCapturedDecl()->setNothrow();
6734   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6735        ThisCaptureLevel > 1; --ThisCaptureLevel) {
6736     CS = cast<CapturedStmt>(CS->getCapturedStmt());
6737     // 1.2.2 OpenMP Language Terminology
6738     // Structured block - An executable statement with a single entry at the
6739     // top and a single exit at the bottom.
6740     // The point of exit cannot be a branch out of the structured block.
6741     // longjmp() and throw() must not violate the entry/exit criteria.
6742     CS->getCapturedDecl()->setNothrow();
6743   }
6744 
6745   OMPLoopDirective::HelperExprs B;
6746   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6747   // define the nested loops number.
6748   unsigned NestedLoopCount =
6749       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6750                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6751                       VarsWithImplicitDSA, B);
6752   if (NestedLoopCount == 0)
6753     return StmtError();
6754 
6755   assert((CurContext->isDependentContext() || B.builtAll()) &&
6756          "omp target parallel for loop exprs were not built");
6757 
6758   if (!CurContext->isDependentContext()) {
6759     // Finalize the clauses that need pre-built expressions for CodeGen.
6760     for (OMPClause *C : Clauses) {
6761       if (auto *LC = dyn_cast<OMPLinearClause>(C))
6762         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6763                                      B.NumIterations, *this, CurScope,
6764                                      DSAStack))
6765           return StmtError();
6766     }
6767   }
6768 
6769   setFunctionHasBranchProtectedScope();
6770   return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6771                                                NestedLoopCount, Clauses, AStmt,
6772                                                B, DSAStack->isCancelRegion());
6773 }
6774 
6775 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)6776 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6777                        const OpenMPClauseKind K) {
6778   return llvm::any_of(
6779       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6780 }
6781 
6782 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)6783 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
6784                        const Params... ClauseTypes) {
6785   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6786 }
6787 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6788 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
6789                                                 Stmt *AStmt,
6790                                                 SourceLocation StartLoc,
6791                                                 SourceLocation EndLoc) {
6792   if (!AStmt)
6793     return StmtError();
6794 
6795   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6796 
6797   // OpenMP [2.10.1, Restrictions, p. 97]
6798   // At least one map clause must appear on the directive.
6799   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6800     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6801         << "'map' or 'use_device_ptr'"
6802         << getOpenMPDirectiveName(OMPD_target_data);
6803     return StmtError();
6804   }
6805 
6806   setFunctionHasBranchProtectedScope();
6807 
6808   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6809                                         AStmt);
6810 }
6811 
6812 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)6813 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
6814                                           SourceLocation StartLoc,
6815                                           SourceLocation EndLoc, Stmt *AStmt) {
6816   if (!AStmt)
6817     return StmtError();
6818 
6819   auto *CS = cast<CapturedStmt>(AStmt);
6820   // 1.2.2 OpenMP Language Terminology
6821   // Structured block - An executable statement with a single entry at the
6822   // top and a single exit at the bottom.
6823   // The point of exit cannot be a branch out of the structured block.
6824   // longjmp() and throw() must not violate the entry/exit criteria.
6825   CS->getCapturedDecl()->setNothrow();
6826   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6827        ThisCaptureLevel > 1; --ThisCaptureLevel) {
6828     CS = cast<CapturedStmt>(CS->getCapturedStmt());
6829     // 1.2.2 OpenMP Language Terminology
6830     // Structured block - An executable statement with a single entry at the
6831     // top and a single exit at the bottom.
6832     // The point of exit cannot be a branch out of the structured block.
6833     // longjmp() and throw() must not violate the entry/exit criteria.
6834     CS->getCapturedDecl()->setNothrow();
6835   }
6836 
6837   // OpenMP [2.10.2, Restrictions, p. 99]
6838   // At least one map clause must appear on the directive.
6839   if (!hasClauses(Clauses, OMPC_map)) {
6840     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6841         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6842     return StmtError();
6843   }
6844 
6845   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6846                                              AStmt);
6847 }
6848 
6849 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)6850 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
6851                                          SourceLocation StartLoc,
6852                                          SourceLocation EndLoc, Stmt *AStmt) {
6853   if (!AStmt)
6854     return StmtError();
6855 
6856   auto *CS = cast<CapturedStmt>(AStmt);
6857   // 1.2.2 OpenMP Language Terminology
6858   // Structured block - An executable statement with a single entry at the
6859   // top and a single exit at the bottom.
6860   // The point of exit cannot be a branch out of the structured block.
6861   // longjmp() and throw() must not violate the entry/exit criteria.
6862   CS->getCapturedDecl()->setNothrow();
6863   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6864        ThisCaptureLevel > 1; --ThisCaptureLevel) {
6865     CS = cast<CapturedStmt>(CS->getCapturedStmt());
6866     // 1.2.2 OpenMP Language Terminology
6867     // Structured block - An executable statement with a single entry at the
6868     // top and a single exit at the bottom.
6869     // The point of exit cannot be a branch out of the structured block.
6870     // longjmp() and throw() must not violate the entry/exit criteria.
6871     CS->getCapturedDecl()->setNothrow();
6872   }
6873 
6874   // OpenMP [2.10.3, Restrictions, p. 102]
6875   // At least one map clause must appear on the directive.
6876   if (!hasClauses(Clauses, OMPC_map)) {
6877     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6878         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6879     return StmtError();
6880   }
6881 
6882   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6883                                             AStmt);
6884 }
6885 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)6886 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
6887                                                   SourceLocation StartLoc,
6888                                                   SourceLocation EndLoc,
6889                                                   Stmt *AStmt) {
6890   if (!AStmt)
6891     return StmtError();
6892 
6893   auto *CS = cast<CapturedStmt>(AStmt);
6894   // 1.2.2 OpenMP Language Terminology
6895   // Structured block - An executable statement with a single entry at the
6896   // top and a single exit at the bottom.
6897   // The point of exit cannot be a branch out of the structured block.
6898   // longjmp() and throw() must not violate the entry/exit criteria.
6899   CS->getCapturedDecl()->setNothrow();
6900   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6901        ThisCaptureLevel > 1; --ThisCaptureLevel) {
6902     CS = cast<CapturedStmt>(CS->getCapturedStmt());
6903     // 1.2.2 OpenMP Language Terminology
6904     // Structured block - An executable statement with a single entry at the
6905     // top and a single exit at the bottom.
6906     // The point of exit cannot be a branch out of the structured block.
6907     // longjmp() and throw() must not violate the entry/exit criteria.
6908     CS->getCapturedDecl()->setNothrow();
6909   }
6910 
6911   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6912     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6913     return StmtError();
6914   }
6915   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6916                                           AStmt);
6917 }
6918 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)6919 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
6920                                            Stmt *AStmt, SourceLocation StartLoc,
6921                                            SourceLocation EndLoc) {
6922   if (!AStmt)
6923     return StmtError();
6924 
6925   auto *CS = cast<CapturedStmt>(AStmt);
6926   // 1.2.2 OpenMP Language Terminology
6927   // Structured block - An executable statement with a single entry at the
6928   // top and a single exit at the bottom.
6929   // The point of exit cannot be a branch out of the structured block.
6930   // longjmp() and throw() must not violate the entry/exit criteria.
6931   CS->getCapturedDecl()->setNothrow();
6932 
6933   setFunctionHasBranchProtectedScope();
6934 
6935   DSAStack->setParentTeamsRegionLoc(StartLoc);
6936 
6937   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6938 }
6939 
6940 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)6941 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
6942                                             SourceLocation EndLoc,
6943                                             OpenMPDirectiveKind CancelRegion) {
6944   if (DSAStack->isParentNowaitRegion()) {
6945     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6946     return StmtError();
6947   }
6948   if (DSAStack->isParentOrderedRegion()) {
6949     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6950     return StmtError();
6951   }
6952   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6953                                                CancelRegion);
6954 }
6955 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)6956 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
6957                                             SourceLocation StartLoc,
6958                                             SourceLocation EndLoc,
6959                                             OpenMPDirectiveKind CancelRegion) {
6960   if (DSAStack->isParentNowaitRegion()) {
6961     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6962     return StmtError();
6963   }
6964   if (DSAStack->isParentOrderedRegion()) {
6965     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6966     return StmtError();
6967   }
6968   DSAStack->setParentCancelRegion(/*Cancel=*/true);
6969   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6970                                     CancelRegion);
6971 }
6972 
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)6973 static bool checkGrainsizeNumTasksClauses(Sema &S,
6974                                           ArrayRef<OMPClause *> Clauses) {
6975   const OMPClause *PrevClause = nullptr;
6976   bool ErrorFound = false;
6977   for (const OMPClause *C : Clauses) {
6978     if (C->getClauseKind() == OMPC_grainsize ||
6979         C->getClauseKind() == OMPC_num_tasks) {
6980       if (!PrevClause)
6981         PrevClause = C;
6982       else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6983         S.Diag(C->getLocStart(),
6984                diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6985             << getOpenMPClauseName(C->getClauseKind())
6986             << getOpenMPClauseName(PrevClause->getClauseKind());
6987         S.Diag(PrevClause->getLocStart(),
6988                diag::note_omp_previous_grainsize_num_tasks)
6989             << getOpenMPClauseName(PrevClause->getClauseKind());
6990         ErrorFound = true;
6991       }
6992     }
6993   }
6994   return ErrorFound;
6995 }
6996 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)6997 static bool checkReductionClauseWithNogroup(Sema &S,
6998                                             ArrayRef<OMPClause *> Clauses) {
6999   const OMPClause *ReductionClause = nullptr;
7000   const OMPClause *NogroupClause = nullptr;
7001   for (const OMPClause *C : Clauses) {
7002     if (C->getClauseKind() == OMPC_reduction) {
7003       ReductionClause = C;
7004       if (NogroupClause)
7005         break;
7006       continue;
7007     }
7008     if (C->getClauseKind() == OMPC_nogroup) {
7009       NogroupClause = C;
7010       if (ReductionClause)
7011         break;
7012       continue;
7013     }
7014   }
7015   if (ReductionClause && NogroupClause) {
7016     S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
7017         << SourceRange(NogroupClause->getLocStart(),
7018                        NogroupClause->getLocEnd());
7019     return true;
7020   }
7021   return false;
7022 }
7023 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7024 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
7025     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7026     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7027   if (!AStmt)
7028     return StmtError();
7029 
7030   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7031   OMPLoopDirective::HelperExprs B;
7032   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7033   // define the nested loops number.
7034   unsigned NestedLoopCount =
7035       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
7036                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7037                       VarsWithImplicitDSA, B);
7038   if (NestedLoopCount == 0)
7039     return StmtError();
7040 
7041   assert((CurContext->isDependentContext() || B.builtAll()) &&
7042          "omp for loop exprs were not built");
7043 
7044   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7045   // The grainsize clause and num_tasks clause are mutually exclusive and may
7046   // not appear on the same taskloop directive.
7047   if (checkGrainsizeNumTasksClauses(*this, Clauses))
7048     return StmtError();
7049   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7050   // If a reduction clause is present on the taskloop directive, the nogroup
7051   // clause must not be specified.
7052   if (checkReductionClauseWithNogroup(*this, Clauses))
7053     return StmtError();
7054 
7055   setFunctionHasBranchProtectedScope();
7056   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
7057                                       NestedLoopCount, Clauses, AStmt, B);
7058 }
7059 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7060 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
7061     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7062     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7063   if (!AStmt)
7064     return StmtError();
7065 
7066   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7067   OMPLoopDirective::HelperExprs B;
7068   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7069   // define the nested loops number.
7070   unsigned NestedLoopCount =
7071       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7072                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7073                       VarsWithImplicitDSA, B);
7074   if (NestedLoopCount == 0)
7075     return StmtError();
7076 
7077   assert((CurContext->isDependentContext() || B.builtAll()) &&
7078          "omp for loop exprs were not built");
7079 
7080   if (!CurContext->isDependentContext()) {
7081     // Finalize the clauses that need pre-built expressions for CodeGen.
7082     for (OMPClause *C : Clauses) {
7083       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7084         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7085                                      B.NumIterations, *this, CurScope,
7086                                      DSAStack))
7087           return StmtError();
7088     }
7089   }
7090 
7091   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7092   // The grainsize clause and num_tasks clause are mutually exclusive and may
7093   // not appear on the same taskloop directive.
7094   if (checkGrainsizeNumTasksClauses(*this, Clauses))
7095     return StmtError();
7096   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7097   // If a reduction clause is present on the taskloop directive, the nogroup
7098   // clause must not be specified.
7099   if (checkReductionClauseWithNogroup(*this, Clauses))
7100     return StmtError();
7101   if (checkSimdlenSafelenSpecified(*this, Clauses))
7102     return StmtError();
7103 
7104   setFunctionHasBranchProtectedScope();
7105   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7106                                           NestedLoopCount, Clauses, AStmt, B);
7107 }
7108 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7109 StmtResult Sema::ActOnOpenMPDistributeDirective(
7110     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7111     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7112   if (!AStmt)
7113     return StmtError();
7114 
7115   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7116   OMPLoopDirective::HelperExprs B;
7117   // In presence of clause 'collapse' with number of loops, it will
7118   // define the nested loops number.
7119   unsigned NestedLoopCount =
7120       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7121                       nullptr /*ordered not a clause on distribute*/, AStmt,
7122                       *this, *DSAStack, VarsWithImplicitDSA, B);
7123   if (NestedLoopCount == 0)
7124     return StmtError();
7125 
7126   assert((CurContext->isDependentContext() || B.builtAll()) &&
7127          "omp for loop exprs were not built");
7128 
7129   setFunctionHasBranchProtectedScope();
7130   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7131                                         NestedLoopCount, Clauses, AStmt, B);
7132 }
7133 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7134 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
7135     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7136     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7137   if (!AStmt)
7138     return StmtError();
7139 
7140   auto *CS = cast<CapturedStmt>(AStmt);
7141   // 1.2.2 OpenMP Language Terminology
7142   // Structured block - An executable statement with a single entry at the
7143   // top and a single exit at the bottom.
7144   // The point of exit cannot be a branch out of the structured block.
7145   // longjmp() and throw() must not violate the entry/exit criteria.
7146   CS->getCapturedDecl()->setNothrow();
7147   for (int ThisCaptureLevel =
7148            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7149        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7150     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7151     // 1.2.2 OpenMP Language Terminology
7152     // Structured block - An executable statement with a single entry at the
7153     // top and a single exit at the bottom.
7154     // The point of exit cannot be a branch out of the structured block.
7155     // longjmp() and throw() must not violate the entry/exit criteria.
7156     CS->getCapturedDecl()->setNothrow();
7157   }
7158 
7159   OMPLoopDirective::HelperExprs B;
7160   // In presence of clause 'collapse' with number of loops, it will
7161   // define the nested loops number.
7162   unsigned NestedLoopCount = checkOpenMPLoop(
7163       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7164       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7165       VarsWithImplicitDSA, B);
7166   if (NestedLoopCount == 0)
7167     return StmtError();
7168 
7169   assert((CurContext->isDependentContext() || B.builtAll()) &&
7170          "omp for loop exprs were not built");
7171 
7172   setFunctionHasBranchProtectedScope();
7173   return OMPDistributeParallelForDirective::Create(
7174       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7175       DSAStack->isCancelRegion());
7176 }
7177 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7178 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
7179     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7180     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7181   if (!AStmt)
7182     return StmtError();
7183 
7184   auto *CS = cast<CapturedStmt>(AStmt);
7185   // 1.2.2 OpenMP Language Terminology
7186   // Structured block - An executable statement with a single entry at the
7187   // top and a single exit at the bottom.
7188   // The point of exit cannot be a branch out of the structured block.
7189   // longjmp() and throw() must not violate the entry/exit criteria.
7190   CS->getCapturedDecl()->setNothrow();
7191   for (int ThisCaptureLevel =
7192            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7193        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7194     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7195     // 1.2.2 OpenMP Language Terminology
7196     // Structured block - An executable statement with a single entry at the
7197     // top and a single exit at the bottom.
7198     // The point of exit cannot be a branch out of the structured block.
7199     // longjmp() and throw() must not violate the entry/exit criteria.
7200     CS->getCapturedDecl()->setNothrow();
7201   }
7202 
7203   OMPLoopDirective::HelperExprs B;
7204   // In presence of clause 'collapse' with number of loops, it will
7205   // define the nested loops number.
7206   unsigned NestedLoopCount = checkOpenMPLoop(
7207       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7208       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7209       VarsWithImplicitDSA, B);
7210   if (NestedLoopCount == 0)
7211     return StmtError();
7212 
7213   assert((CurContext->isDependentContext() || B.builtAll()) &&
7214          "omp for loop exprs were not built");
7215 
7216   if (!CurContext->isDependentContext()) {
7217     // Finalize the clauses that need pre-built expressions for CodeGen.
7218     for (OMPClause *C : Clauses) {
7219       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7220         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7221                                      B.NumIterations, *this, CurScope,
7222                                      DSAStack))
7223           return StmtError();
7224     }
7225   }
7226 
7227   if (checkSimdlenSafelenSpecified(*this, Clauses))
7228     return StmtError();
7229 
7230   setFunctionHasBranchProtectedScope();
7231   return OMPDistributeParallelForSimdDirective::Create(
7232       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7233 }
7234 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7235 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
7236     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7237     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7238   if (!AStmt)
7239     return StmtError();
7240 
7241   auto *CS = cast<CapturedStmt>(AStmt);
7242   // 1.2.2 OpenMP Language Terminology
7243   // Structured block - An executable statement with a single entry at the
7244   // top and a single exit at the bottom.
7245   // The point of exit cannot be a branch out of the structured block.
7246   // longjmp() and throw() must not violate the entry/exit criteria.
7247   CS->getCapturedDecl()->setNothrow();
7248   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7249        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7250     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7251     // 1.2.2 OpenMP Language Terminology
7252     // Structured block - An executable statement with a single entry at the
7253     // top and a single exit at the bottom.
7254     // The point of exit cannot be a branch out of the structured block.
7255     // longjmp() and throw() must not violate the entry/exit criteria.
7256     CS->getCapturedDecl()->setNothrow();
7257   }
7258 
7259   OMPLoopDirective::HelperExprs B;
7260   // In presence of clause 'collapse' with number of loops, it will
7261   // define the nested loops number.
7262   unsigned NestedLoopCount =
7263       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7264                       nullptr /*ordered not a clause on distribute*/, CS, *this,
7265                       *DSAStack, VarsWithImplicitDSA, B);
7266   if (NestedLoopCount == 0)
7267     return StmtError();
7268 
7269   assert((CurContext->isDependentContext() || B.builtAll()) &&
7270          "omp for loop exprs were not built");
7271 
7272   if (!CurContext->isDependentContext()) {
7273     // Finalize the clauses that need pre-built expressions for CodeGen.
7274     for (OMPClause *C : Clauses) {
7275       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7276         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7277                                      B.NumIterations, *this, CurScope,
7278                                      DSAStack))
7279           return StmtError();
7280     }
7281   }
7282 
7283   if (checkSimdlenSafelenSpecified(*this, Clauses))
7284     return StmtError();
7285 
7286   setFunctionHasBranchProtectedScope();
7287   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7288                                             NestedLoopCount, Clauses, AStmt, B);
7289 }
7290 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7291 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
7292     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7293     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7294   if (!AStmt)
7295     return StmtError();
7296 
7297   auto *CS = cast<CapturedStmt>(AStmt);
7298   // 1.2.2 OpenMP Language Terminology
7299   // Structured block - An executable statement with a single entry at the
7300   // top and a single exit at the bottom.
7301   // The point of exit cannot be a branch out of the structured block.
7302   // longjmp() and throw() must not violate the entry/exit criteria.
7303   CS->getCapturedDecl()->setNothrow();
7304   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7305        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7306     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7307     // 1.2.2 OpenMP Language Terminology
7308     // Structured block - An executable statement with a single entry at the
7309     // top and a single exit at the bottom.
7310     // The point of exit cannot be a branch out of the structured block.
7311     // longjmp() and throw() must not violate the entry/exit criteria.
7312     CS->getCapturedDecl()->setNothrow();
7313   }
7314 
7315   OMPLoopDirective::HelperExprs B;
7316   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7317   // define the nested loops number.
7318   unsigned NestedLoopCount = checkOpenMPLoop(
7319       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7320       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7321       VarsWithImplicitDSA, B);
7322   if (NestedLoopCount == 0)
7323     return StmtError();
7324 
7325   assert((CurContext->isDependentContext() || B.builtAll()) &&
7326          "omp target parallel for simd loop exprs were not built");
7327 
7328   if (!CurContext->isDependentContext()) {
7329     // Finalize the clauses that need pre-built expressions for CodeGen.
7330     for (OMPClause *C : Clauses) {
7331       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7332         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7333                                      B.NumIterations, *this, CurScope,
7334                                      DSAStack))
7335           return StmtError();
7336     }
7337   }
7338   if (checkSimdlenSafelenSpecified(*this, Clauses))
7339     return StmtError();
7340 
7341   setFunctionHasBranchProtectedScope();
7342   return OMPTargetParallelForSimdDirective::Create(
7343       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7344 }
7345 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7346 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
7347     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7348     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7349   if (!AStmt)
7350     return StmtError();
7351 
7352   auto *CS = cast<CapturedStmt>(AStmt);
7353   // 1.2.2 OpenMP Language Terminology
7354   // Structured block - An executable statement with a single entry at the
7355   // top and a single exit at the bottom.
7356   // The point of exit cannot be a branch out of the structured block.
7357   // longjmp() and throw() must not violate the entry/exit criteria.
7358   CS->getCapturedDecl()->setNothrow();
7359   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7360        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7361     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7362     // 1.2.2 OpenMP Language Terminology
7363     // Structured block - An executable statement with a single entry at the
7364     // top and a single exit at the bottom.
7365     // The point of exit cannot be a branch out of the structured block.
7366     // longjmp() and throw() must not violate the entry/exit criteria.
7367     CS->getCapturedDecl()->setNothrow();
7368   }
7369 
7370   OMPLoopDirective::HelperExprs B;
7371   // In presence of clause 'collapse' with number of loops, it will define the
7372   // nested loops number.
7373   unsigned NestedLoopCount =
7374       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7375                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7376                       VarsWithImplicitDSA, B);
7377   if (NestedLoopCount == 0)
7378     return StmtError();
7379 
7380   assert((CurContext->isDependentContext() || B.builtAll()) &&
7381          "omp target simd loop exprs were not built");
7382 
7383   if (!CurContext->isDependentContext()) {
7384     // Finalize the clauses that need pre-built expressions for CodeGen.
7385     for (OMPClause *C : Clauses) {
7386       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7387         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7388                                      B.NumIterations, *this, CurScope,
7389                                      DSAStack))
7390           return StmtError();
7391     }
7392   }
7393 
7394   if (checkSimdlenSafelenSpecified(*this, Clauses))
7395     return StmtError();
7396 
7397   setFunctionHasBranchProtectedScope();
7398   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7399                                         NestedLoopCount, Clauses, AStmt, B);
7400 }
7401 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7402 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
7403     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7404     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7405   if (!AStmt)
7406     return StmtError();
7407 
7408   auto *CS = cast<CapturedStmt>(AStmt);
7409   // 1.2.2 OpenMP Language Terminology
7410   // Structured block - An executable statement with a single entry at the
7411   // top and a single exit at the bottom.
7412   // The point of exit cannot be a branch out of the structured block.
7413   // longjmp() and throw() must not violate the entry/exit criteria.
7414   CS->getCapturedDecl()->setNothrow();
7415   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7416        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7417     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7418     // 1.2.2 OpenMP Language Terminology
7419     // Structured block - An executable statement with a single entry at the
7420     // top and a single exit at the bottom.
7421     // The point of exit cannot be a branch out of the structured block.
7422     // longjmp() and throw() must not violate the entry/exit criteria.
7423     CS->getCapturedDecl()->setNothrow();
7424   }
7425 
7426   OMPLoopDirective::HelperExprs B;
7427   // In presence of clause 'collapse' with number of loops, it will
7428   // define the nested loops number.
7429   unsigned NestedLoopCount =
7430       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7431                       nullptr /*ordered not a clause on distribute*/, CS, *this,
7432                       *DSAStack, VarsWithImplicitDSA, B);
7433   if (NestedLoopCount == 0)
7434     return StmtError();
7435 
7436   assert((CurContext->isDependentContext() || B.builtAll()) &&
7437          "omp teams distribute loop exprs were not built");
7438 
7439   setFunctionHasBranchProtectedScope();
7440 
7441   DSAStack->setParentTeamsRegionLoc(StartLoc);
7442 
7443   return OMPTeamsDistributeDirective::Create(
7444       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7445 }
7446 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7447 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
7448     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7449     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7450   if (!AStmt)
7451     return StmtError();
7452 
7453   auto *CS = cast<CapturedStmt>(AStmt);
7454   // 1.2.2 OpenMP Language Terminology
7455   // Structured block - An executable statement with a single entry at the
7456   // top and a single exit at the bottom.
7457   // The point of exit cannot be a branch out of the structured block.
7458   // longjmp() and throw() must not violate the entry/exit criteria.
7459   CS->getCapturedDecl()->setNothrow();
7460   for (int ThisCaptureLevel =
7461            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7462        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7463     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7464     // 1.2.2 OpenMP Language Terminology
7465     // Structured block - An executable statement with a single entry at the
7466     // top and a single exit at the bottom.
7467     // The point of exit cannot be a branch out of the structured block.
7468     // longjmp() and throw() must not violate the entry/exit criteria.
7469     CS->getCapturedDecl()->setNothrow();
7470   }
7471 
7472 
7473   OMPLoopDirective::HelperExprs B;
7474   // In presence of clause 'collapse' with number of loops, it will
7475   // define the nested loops number.
7476   unsigned NestedLoopCount = checkOpenMPLoop(
7477       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7478       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7479       VarsWithImplicitDSA, B);
7480 
7481   if (NestedLoopCount == 0)
7482     return StmtError();
7483 
7484   assert((CurContext->isDependentContext() || B.builtAll()) &&
7485          "omp teams distribute simd loop exprs were not built");
7486 
7487   if (!CurContext->isDependentContext()) {
7488     // Finalize the clauses that need pre-built expressions for CodeGen.
7489     for (OMPClause *C : Clauses) {
7490       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7491         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7492                                      B.NumIterations, *this, CurScope,
7493                                      DSAStack))
7494           return StmtError();
7495     }
7496   }
7497 
7498   if (checkSimdlenSafelenSpecified(*this, Clauses))
7499     return StmtError();
7500 
7501   setFunctionHasBranchProtectedScope();
7502 
7503   DSAStack->setParentTeamsRegionLoc(StartLoc);
7504 
7505   return OMPTeamsDistributeSimdDirective::Create(
7506       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7507 }
7508 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7509 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
7510     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7511     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7512   if (!AStmt)
7513     return StmtError();
7514 
7515   auto *CS = cast<CapturedStmt>(AStmt);
7516   // 1.2.2 OpenMP Language Terminology
7517   // Structured block - An executable statement with a single entry at the
7518   // top and a single exit at the bottom.
7519   // The point of exit cannot be a branch out of the structured block.
7520   // longjmp() and throw() must not violate the entry/exit criteria.
7521   CS->getCapturedDecl()->setNothrow();
7522 
7523   for (int ThisCaptureLevel =
7524            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7525        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7526     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7527     // 1.2.2 OpenMP Language Terminology
7528     // Structured block - An executable statement with a single entry at the
7529     // top and a single exit at the bottom.
7530     // The point of exit cannot be a branch out of the structured block.
7531     // longjmp() and throw() must not violate the entry/exit criteria.
7532     CS->getCapturedDecl()->setNothrow();
7533   }
7534 
7535   OMPLoopDirective::HelperExprs B;
7536   // In presence of clause 'collapse' with number of loops, it will
7537   // define the nested loops number.
7538   unsigned NestedLoopCount = checkOpenMPLoop(
7539       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7540       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7541       VarsWithImplicitDSA, B);
7542 
7543   if (NestedLoopCount == 0)
7544     return StmtError();
7545 
7546   assert((CurContext->isDependentContext() || B.builtAll()) &&
7547          "omp for loop exprs were not built");
7548 
7549   if (!CurContext->isDependentContext()) {
7550     // Finalize the clauses that need pre-built expressions for CodeGen.
7551     for (OMPClause *C : Clauses) {
7552       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7553         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7554                                      B.NumIterations, *this, CurScope,
7555                                      DSAStack))
7556           return StmtError();
7557     }
7558   }
7559 
7560   if (checkSimdlenSafelenSpecified(*this, Clauses))
7561     return StmtError();
7562 
7563   setFunctionHasBranchProtectedScope();
7564 
7565   DSAStack->setParentTeamsRegionLoc(StartLoc);
7566 
7567   return OMPTeamsDistributeParallelForSimdDirective::Create(
7568       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7569 }
7570 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7571 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
7572     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7573     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7574   if (!AStmt)
7575     return StmtError();
7576 
7577   auto *CS = cast<CapturedStmt>(AStmt);
7578   // 1.2.2 OpenMP Language Terminology
7579   // Structured block - An executable statement with a single entry at the
7580   // top and a single exit at the bottom.
7581   // The point of exit cannot be a branch out of the structured block.
7582   // longjmp() and throw() must not violate the entry/exit criteria.
7583   CS->getCapturedDecl()->setNothrow();
7584 
7585   for (int ThisCaptureLevel =
7586            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7587        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7588     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7589     // 1.2.2 OpenMP Language Terminology
7590     // Structured block - An executable statement with a single entry at the
7591     // top and a single exit at the bottom.
7592     // The point of exit cannot be a branch out of the structured block.
7593     // longjmp() and throw() must not violate the entry/exit criteria.
7594     CS->getCapturedDecl()->setNothrow();
7595   }
7596 
7597   OMPLoopDirective::HelperExprs B;
7598   // In presence of clause 'collapse' with number of loops, it will
7599   // define the nested loops number.
7600   unsigned NestedLoopCount = checkOpenMPLoop(
7601       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7602       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7603       VarsWithImplicitDSA, B);
7604 
7605   if (NestedLoopCount == 0)
7606     return StmtError();
7607 
7608   assert((CurContext->isDependentContext() || B.builtAll()) &&
7609          "omp for loop exprs were not built");
7610 
7611   setFunctionHasBranchProtectedScope();
7612 
7613   DSAStack->setParentTeamsRegionLoc(StartLoc);
7614 
7615   return OMPTeamsDistributeParallelForDirective::Create(
7616       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7617       DSAStack->isCancelRegion());
7618 }
7619 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7620 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
7621                                                  Stmt *AStmt,
7622                                                  SourceLocation StartLoc,
7623                                                  SourceLocation EndLoc) {
7624   if (!AStmt)
7625     return StmtError();
7626 
7627   auto *CS = cast<CapturedStmt>(AStmt);
7628   // 1.2.2 OpenMP Language Terminology
7629   // Structured block - An executable statement with a single entry at the
7630   // top and a single exit at the bottom.
7631   // The point of exit cannot be a branch out of the structured block.
7632   // longjmp() and throw() must not violate the entry/exit criteria.
7633   CS->getCapturedDecl()->setNothrow();
7634 
7635   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7636        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7637     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7638     // 1.2.2 OpenMP Language Terminology
7639     // Structured block - An executable statement with a single entry at the
7640     // top and a single exit at the bottom.
7641     // The point of exit cannot be a branch out of the structured block.
7642     // longjmp() and throw() must not violate the entry/exit criteria.
7643     CS->getCapturedDecl()->setNothrow();
7644   }
7645   setFunctionHasBranchProtectedScope();
7646 
7647   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7648                                          AStmt);
7649 }
7650 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7651 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
7652     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7653     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7654   if (!AStmt)
7655     return StmtError();
7656 
7657   auto *CS = cast<CapturedStmt>(AStmt);
7658   // 1.2.2 OpenMP Language Terminology
7659   // Structured block - An executable statement with a single entry at the
7660   // top and a single exit at the bottom.
7661   // The point of exit cannot be a branch out of the structured block.
7662   // longjmp() and throw() must not violate the entry/exit criteria.
7663   CS->getCapturedDecl()->setNothrow();
7664   for (int ThisCaptureLevel =
7665            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7666        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7667     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7668     // 1.2.2 OpenMP Language Terminology
7669     // Structured block - An executable statement with a single entry at the
7670     // top and a single exit at the bottom.
7671     // The point of exit cannot be a branch out of the structured block.
7672     // longjmp() and throw() must not violate the entry/exit criteria.
7673     CS->getCapturedDecl()->setNothrow();
7674   }
7675 
7676   OMPLoopDirective::HelperExprs B;
7677   // In presence of clause 'collapse' with number of loops, it will
7678   // define the nested loops number.
7679   unsigned NestedLoopCount = checkOpenMPLoop(
7680       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7681       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7682       VarsWithImplicitDSA, B);
7683   if (NestedLoopCount == 0)
7684     return StmtError();
7685 
7686   assert((CurContext->isDependentContext() || B.builtAll()) &&
7687          "omp target teams distribute loop exprs were not built");
7688 
7689   setFunctionHasBranchProtectedScope();
7690   return OMPTargetTeamsDistributeDirective::Create(
7691       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7692 }
7693 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7694 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
7695     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7696     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7697   if (!AStmt)
7698     return StmtError();
7699 
7700   auto *CS = cast<CapturedStmt>(AStmt);
7701   // 1.2.2 OpenMP Language Terminology
7702   // Structured block - An executable statement with a single entry at the
7703   // top and a single exit at the bottom.
7704   // The point of exit cannot be a branch out of the structured block.
7705   // longjmp() and throw() must not violate the entry/exit criteria.
7706   CS->getCapturedDecl()->setNothrow();
7707   for (int ThisCaptureLevel =
7708            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
7709        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7710     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7711     // 1.2.2 OpenMP Language Terminology
7712     // Structured block - An executable statement with a single entry at the
7713     // top and a single exit at the bottom.
7714     // The point of exit cannot be a branch out of the structured block.
7715     // longjmp() and throw() must not violate the entry/exit criteria.
7716     CS->getCapturedDecl()->setNothrow();
7717   }
7718 
7719   OMPLoopDirective::HelperExprs B;
7720   // In presence of clause 'collapse' with number of loops, it will
7721   // define the nested loops number.
7722   unsigned NestedLoopCount = checkOpenMPLoop(
7723       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7724       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7725       VarsWithImplicitDSA, B);
7726   if (NestedLoopCount == 0)
7727     return StmtError();
7728 
7729   assert((CurContext->isDependentContext() || B.builtAll()) &&
7730          "omp target teams distribute parallel for loop exprs were not built");
7731 
7732   if (!CurContext->isDependentContext()) {
7733     // Finalize the clauses that need pre-built expressions for CodeGen.
7734     for (OMPClause *C : Clauses) {
7735       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7736         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7737                                      B.NumIterations, *this, CurScope,
7738                                      DSAStack))
7739           return StmtError();
7740     }
7741   }
7742 
7743   setFunctionHasBranchProtectedScope();
7744   return OMPTargetTeamsDistributeParallelForDirective::Create(
7745       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7746       DSAStack->isCancelRegion());
7747 }
7748 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7749 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
7750     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7751     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7752   if (!AStmt)
7753     return StmtError();
7754 
7755   auto *CS = cast<CapturedStmt>(AStmt);
7756   // 1.2.2 OpenMP Language Terminology
7757   // Structured block - An executable statement with a single entry at the
7758   // top and a single exit at the bottom.
7759   // The point of exit cannot be a branch out of the structured block.
7760   // longjmp() and throw() must not violate the entry/exit criteria.
7761   CS->getCapturedDecl()->setNothrow();
7762   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
7763            OMPD_target_teams_distribute_parallel_for_simd);
7764        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7765     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7766     // 1.2.2 OpenMP Language Terminology
7767     // Structured block - An executable statement with a single entry at the
7768     // top and a single exit at the bottom.
7769     // The point of exit cannot be a branch out of the structured block.
7770     // longjmp() and throw() must not violate the entry/exit criteria.
7771     CS->getCapturedDecl()->setNothrow();
7772   }
7773 
7774   OMPLoopDirective::HelperExprs B;
7775   // In presence of clause 'collapse' with number of loops, it will
7776   // define the nested loops number.
7777   unsigned NestedLoopCount =
7778       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
7779                       getCollapseNumberExpr(Clauses),
7780                       nullptr /*ordered not a clause on distribute*/, CS, *this,
7781                       *DSAStack, VarsWithImplicitDSA, B);
7782   if (NestedLoopCount == 0)
7783     return StmtError();
7784 
7785   assert((CurContext->isDependentContext() || B.builtAll()) &&
7786          "omp target teams distribute parallel for simd loop exprs were not "
7787          "built");
7788 
7789   if (!CurContext->isDependentContext()) {
7790     // Finalize the clauses that need pre-built expressions for CodeGen.
7791     for (OMPClause *C : Clauses) {
7792       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7793         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7794                                      B.NumIterations, *this, CurScope,
7795                                      DSAStack))
7796           return StmtError();
7797     }
7798   }
7799 
7800   if (checkSimdlenSafelenSpecified(*this, Clauses))
7801     return StmtError();
7802 
7803   setFunctionHasBranchProtectedScope();
7804   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
7805       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7806 }
7807 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)7808 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
7809     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7810     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7811   if (!AStmt)
7812     return StmtError();
7813 
7814   auto *CS = cast<CapturedStmt>(AStmt);
7815   // 1.2.2 OpenMP Language Terminology
7816   // Structured block - An executable statement with a single entry at the
7817   // top and a single exit at the bottom.
7818   // The point of exit cannot be a branch out of the structured block.
7819   // longjmp() and throw() must not violate the entry/exit criteria.
7820   CS->getCapturedDecl()->setNothrow();
7821   for (int ThisCaptureLevel =
7822            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7823        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7824     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7825     // 1.2.2 OpenMP Language Terminology
7826     // Structured block - An executable statement with a single entry at the
7827     // top and a single exit at the bottom.
7828     // The point of exit cannot be a branch out of the structured block.
7829     // longjmp() and throw() must not violate the entry/exit criteria.
7830     CS->getCapturedDecl()->setNothrow();
7831   }
7832 
7833   OMPLoopDirective::HelperExprs B;
7834   // In presence of clause 'collapse' with number of loops, it will
7835   // define the nested loops number.
7836   unsigned NestedLoopCount = checkOpenMPLoop(
7837       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7838       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7839       VarsWithImplicitDSA, B);
7840   if (NestedLoopCount == 0)
7841     return StmtError();
7842 
7843   assert((CurContext->isDependentContext() || B.builtAll()) &&
7844          "omp target teams distribute simd loop exprs were not built");
7845 
7846   if (!CurContext->isDependentContext()) {
7847     // Finalize the clauses that need pre-built expressions for CodeGen.
7848     for (OMPClause *C : Clauses) {
7849       if (auto *LC = dyn_cast<OMPLinearClause>(C))
7850         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7851                                      B.NumIterations, *this, CurScope,
7852                                      DSAStack))
7853           return StmtError();
7854     }
7855   }
7856 
7857   if (checkSimdlenSafelenSpecified(*this, Clauses))
7858     return StmtError();
7859 
7860   setFunctionHasBranchProtectedScope();
7861   return OMPTargetTeamsDistributeSimdDirective::Create(
7862       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7863 }
7864 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)7865 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
7866                                              SourceLocation StartLoc,
7867                                              SourceLocation LParenLoc,
7868                                              SourceLocation EndLoc) {
7869   OMPClause *Res = nullptr;
7870   switch (Kind) {
7871   case OMPC_final:
7872     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7873     break;
7874   case OMPC_num_threads:
7875     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7876     break;
7877   case OMPC_safelen:
7878     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7879     break;
7880   case OMPC_simdlen:
7881     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7882     break;
7883   case OMPC_collapse:
7884     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7885     break;
7886   case OMPC_ordered:
7887     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7888     break;
7889   case OMPC_device:
7890     Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7891     break;
7892   case OMPC_num_teams:
7893     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7894     break;
7895   case OMPC_thread_limit:
7896     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7897     break;
7898   case OMPC_priority:
7899     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7900     break;
7901   case OMPC_grainsize:
7902     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7903     break;
7904   case OMPC_num_tasks:
7905     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7906     break;
7907   case OMPC_hint:
7908     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7909     break;
7910   case OMPC_if:
7911   case OMPC_default:
7912   case OMPC_proc_bind:
7913   case OMPC_schedule:
7914   case OMPC_private:
7915   case OMPC_firstprivate:
7916   case OMPC_lastprivate:
7917   case OMPC_shared:
7918   case OMPC_reduction:
7919   case OMPC_task_reduction:
7920   case OMPC_in_reduction:
7921   case OMPC_linear:
7922   case OMPC_aligned:
7923   case OMPC_copyin:
7924   case OMPC_copyprivate:
7925   case OMPC_nowait:
7926   case OMPC_untied:
7927   case OMPC_mergeable:
7928   case OMPC_threadprivate:
7929   case OMPC_flush:
7930   case OMPC_read:
7931   case OMPC_write:
7932   case OMPC_update:
7933   case OMPC_capture:
7934   case OMPC_seq_cst:
7935   case OMPC_depend:
7936   case OMPC_threads:
7937   case OMPC_simd:
7938   case OMPC_map:
7939   case OMPC_nogroup:
7940   case OMPC_dist_schedule:
7941   case OMPC_defaultmap:
7942   case OMPC_unknown:
7943   case OMPC_uniform:
7944   case OMPC_to:
7945   case OMPC_from:
7946   case OMPC_use_device_ptr:
7947   case OMPC_is_device_ptr:
7948     llvm_unreachable("Clause is not allowed.");
7949   }
7950   return Res;
7951 }
7952 
7953 // An OpenMP directive such as 'target parallel' has two captured regions:
7954 // for the 'target' and 'parallel' respectively.  This function returns
7955 // the region in which to capture expressions associated with a clause.
7956 // A return value of OMPD_unknown signifies that the expression should not
7957 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,OpenMPDirectiveKind NameModifier=OMPD_unknown)7958 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
7959     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
7960     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
7961   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
7962   switch (CKind) {
7963   case OMPC_if:
7964     switch (DKind) {
7965     case OMPD_target_parallel:
7966     case OMPD_target_parallel_for:
7967     case OMPD_target_parallel_for_simd:
7968       // If this clause applies to the nested 'parallel' region, capture within
7969       // the 'target' region, otherwise do not capture.
7970       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7971         CaptureRegion = OMPD_target;
7972       break;
7973     case OMPD_target_teams_distribute_parallel_for:
7974     case OMPD_target_teams_distribute_parallel_for_simd:
7975       // If this clause applies to the nested 'parallel' region, capture within
7976       // the 'teams' region, otherwise do not capture.
7977       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7978         CaptureRegion = OMPD_teams;
7979       break;
7980     case OMPD_teams_distribute_parallel_for:
7981     case OMPD_teams_distribute_parallel_for_simd:
7982       CaptureRegion = OMPD_teams;
7983       break;
7984     case OMPD_target_update:
7985     case OMPD_target_enter_data:
7986     case OMPD_target_exit_data:
7987       CaptureRegion = OMPD_task;
7988       break;
7989     case OMPD_cancel:
7990     case OMPD_parallel:
7991     case OMPD_parallel_sections:
7992     case OMPD_parallel_for:
7993     case OMPD_parallel_for_simd:
7994     case OMPD_target:
7995     case OMPD_target_simd:
7996     case OMPD_target_teams:
7997     case OMPD_target_teams_distribute:
7998     case OMPD_target_teams_distribute_simd:
7999     case OMPD_distribute_parallel_for:
8000     case OMPD_distribute_parallel_for_simd:
8001     case OMPD_task:
8002     case OMPD_taskloop:
8003     case OMPD_taskloop_simd:
8004     case OMPD_target_data:
8005       // Do not capture if-clause expressions.
8006       break;
8007     case OMPD_threadprivate:
8008     case OMPD_taskyield:
8009     case OMPD_barrier:
8010     case OMPD_taskwait:
8011     case OMPD_cancellation_point:
8012     case OMPD_flush:
8013     case OMPD_declare_reduction:
8014     case OMPD_declare_simd:
8015     case OMPD_declare_target:
8016     case OMPD_end_declare_target:
8017     case OMPD_teams:
8018     case OMPD_simd:
8019     case OMPD_for:
8020     case OMPD_for_simd:
8021     case OMPD_sections:
8022     case OMPD_section:
8023     case OMPD_single:
8024     case OMPD_master:
8025     case OMPD_critical:
8026     case OMPD_taskgroup:
8027     case OMPD_distribute:
8028     case OMPD_ordered:
8029     case OMPD_atomic:
8030     case OMPD_distribute_simd:
8031     case OMPD_teams_distribute:
8032     case OMPD_teams_distribute_simd:
8033       llvm_unreachable("Unexpected OpenMP directive with if-clause");
8034     case OMPD_unknown:
8035       llvm_unreachable("Unknown OpenMP directive");
8036     }
8037     break;
8038   case OMPC_num_threads:
8039     switch (DKind) {
8040     case OMPD_target_parallel:
8041     case OMPD_target_parallel_for:
8042     case OMPD_target_parallel_for_simd:
8043       CaptureRegion = OMPD_target;
8044       break;
8045     case OMPD_teams_distribute_parallel_for:
8046     case OMPD_teams_distribute_parallel_for_simd:
8047     case OMPD_target_teams_distribute_parallel_for:
8048     case OMPD_target_teams_distribute_parallel_for_simd:
8049       CaptureRegion = OMPD_teams;
8050       break;
8051     case OMPD_parallel:
8052     case OMPD_parallel_sections:
8053     case OMPD_parallel_for:
8054     case OMPD_parallel_for_simd:
8055     case OMPD_distribute_parallel_for:
8056     case OMPD_distribute_parallel_for_simd:
8057       // Do not capture num_threads-clause expressions.
8058       break;
8059     case OMPD_target_data:
8060     case OMPD_target_enter_data:
8061     case OMPD_target_exit_data:
8062     case OMPD_target_update:
8063     case OMPD_target:
8064     case OMPD_target_simd:
8065     case OMPD_target_teams:
8066     case OMPD_target_teams_distribute:
8067     case OMPD_target_teams_distribute_simd:
8068     case OMPD_cancel:
8069     case OMPD_task:
8070     case OMPD_taskloop:
8071     case OMPD_taskloop_simd:
8072     case OMPD_threadprivate:
8073     case OMPD_taskyield:
8074     case OMPD_barrier:
8075     case OMPD_taskwait:
8076     case OMPD_cancellation_point:
8077     case OMPD_flush:
8078     case OMPD_declare_reduction:
8079     case OMPD_declare_simd:
8080     case OMPD_declare_target:
8081     case OMPD_end_declare_target:
8082     case OMPD_teams:
8083     case OMPD_simd:
8084     case OMPD_for:
8085     case OMPD_for_simd:
8086     case OMPD_sections:
8087     case OMPD_section:
8088     case OMPD_single:
8089     case OMPD_master:
8090     case OMPD_critical:
8091     case OMPD_taskgroup:
8092     case OMPD_distribute:
8093     case OMPD_ordered:
8094     case OMPD_atomic:
8095     case OMPD_distribute_simd:
8096     case OMPD_teams_distribute:
8097     case OMPD_teams_distribute_simd:
8098       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
8099     case OMPD_unknown:
8100       llvm_unreachable("Unknown OpenMP directive");
8101     }
8102     break;
8103   case OMPC_num_teams:
8104     switch (DKind) {
8105     case OMPD_target_teams:
8106     case OMPD_target_teams_distribute:
8107     case OMPD_target_teams_distribute_simd:
8108     case OMPD_target_teams_distribute_parallel_for:
8109     case OMPD_target_teams_distribute_parallel_for_simd:
8110       CaptureRegion = OMPD_target;
8111       break;
8112     case OMPD_teams_distribute_parallel_for:
8113     case OMPD_teams_distribute_parallel_for_simd:
8114     case OMPD_teams:
8115     case OMPD_teams_distribute:
8116     case OMPD_teams_distribute_simd:
8117       // Do not capture num_teams-clause expressions.
8118       break;
8119     case OMPD_distribute_parallel_for:
8120     case OMPD_distribute_parallel_for_simd:
8121     case OMPD_task:
8122     case OMPD_taskloop:
8123     case OMPD_taskloop_simd:
8124     case OMPD_target_data:
8125     case OMPD_target_enter_data:
8126     case OMPD_target_exit_data:
8127     case OMPD_target_update:
8128     case OMPD_cancel:
8129     case OMPD_parallel:
8130     case OMPD_parallel_sections:
8131     case OMPD_parallel_for:
8132     case OMPD_parallel_for_simd:
8133     case OMPD_target:
8134     case OMPD_target_simd:
8135     case OMPD_target_parallel:
8136     case OMPD_target_parallel_for:
8137     case OMPD_target_parallel_for_simd:
8138     case OMPD_threadprivate:
8139     case OMPD_taskyield:
8140     case OMPD_barrier:
8141     case OMPD_taskwait:
8142     case OMPD_cancellation_point:
8143     case OMPD_flush:
8144     case OMPD_declare_reduction:
8145     case OMPD_declare_simd:
8146     case OMPD_declare_target:
8147     case OMPD_end_declare_target:
8148     case OMPD_simd:
8149     case OMPD_for:
8150     case OMPD_for_simd:
8151     case OMPD_sections:
8152     case OMPD_section:
8153     case OMPD_single:
8154     case OMPD_master:
8155     case OMPD_critical:
8156     case OMPD_taskgroup:
8157     case OMPD_distribute:
8158     case OMPD_ordered:
8159     case OMPD_atomic:
8160     case OMPD_distribute_simd:
8161       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8162     case OMPD_unknown:
8163       llvm_unreachable("Unknown OpenMP directive");
8164     }
8165     break;
8166   case OMPC_thread_limit:
8167     switch (DKind) {
8168     case OMPD_target_teams:
8169     case OMPD_target_teams_distribute:
8170     case OMPD_target_teams_distribute_simd:
8171     case OMPD_target_teams_distribute_parallel_for:
8172     case OMPD_target_teams_distribute_parallel_for_simd:
8173       CaptureRegion = OMPD_target;
8174       break;
8175     case OMPD_teams_distribute_parallel_for:
8176     case OMPD_teams_distribute_parallel_for_simd:
8177     case OMPD_teams:
8178     case OMPD_teams_distribute:
8179     case OMPD_teams_distribute_simd:
8180       // Do not capture thread_limit-clause expressions.
8181       break;
8182     case OMPD_distribute_parallel_for:
8183     case OMPD_distribute_parallel_for_simd:
8184     case OMPD_task:
8185     case OMPD_taskloop:
8186     case OMPD_taskloop_simd:
8187     case OMPD_target_data:
8188     case OMPD_target_enter_data:
8189     case OMPD_target_exit_data:
8190     case OMPD_target_update:
8191     case OMPD_cancel:
8192     case OMPD_parallel:
8193     case OMPD_parallel_sections:
8194     case OMPD_parallel_for:
8195     case OMPD_parallel_for_simd:
8196     case OMPD_target:
8197     case OMPD_target_simd:
8198     case OMPD_target_parallel:
8199     case OMPD_target_parallel_for:
8200     case OMPD_target_parallel_for_simd:
8201     case OMPD_threadprivate:
8202     case OMPD_taskyield:
8203     case OMPD_barrier:
8204     case OMPD_taskwait:
8205     case OMPD_cancellation_point:
8206     case OMPD_flush:
8207     case OMPD_declare_reduction:
8208     case OMPD_declare_simd:
8209     case OMPD_declare_target:
8210     case OMPD_end_declare_target:
8211     case OMPD_simd:
8212     case OMPD_for:
8213     case OMPD_for_simd:
8214     case OMPD_sections:
8215     case OMPD_section:
8216     case OMPD_single:
8217     case OMPD_master:
8218     case OMPD_critical:
8219     case OMPD_taskgroup:
8220     case OMPD_distribute:
8221     case OMPD_ordered:
8222     case OMPD_atomic:
8223     case OMPD_distribute_simd:
8224       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
8225     case OMPD_unknown:
8226       llvm_unreachable("Unknown OpenMP directive");
8227     }
8228     break;
8229   case OMPC_schedule:
8230     switch (DKind) {
8231     case OMPD_parallel_for:
8232     case OMPD_parallel_for_simd:
8233     case OMPD_distribute_parallel_for:
8234     case OMPD_distribute_parallel_for_simd:
8235     case OMPD_teams_distribute_parallel_for:
8236     case OMPD_teams_distribute_parallel_for_simd:
8237     case OMPD_target_parallel_for:
8238     case OMPD_target_parallel_for_simd:
8239     case OMPD_target_teams_distribute_parallel_for:
8240     case OMPD_target_teams_distribute_parallel_for_simd:
8241       CaptureRegion = OMPD_parallel;
8242       break;
8243     case OMPD_for:
8244     case OMPD_for_simd:
8245       // Do not capture schedule-clause expressions.
8246       break;
8247     case OMPD_task:
8248     case OMPD_taskloop:
8249     case OMPD_taskloop_simd:
8250     case OMPD_target_data:
8251     case OMPD_target_enter_data:
8252     case OMPD_target_exit_data:
8253     case OMPD_target_update:
8254     case OMPD_teams:
8255     case OMPD_teams_distribute:
8256     case OMPD_teams_distribute_simd:
8257     case OMPD_target_teams_distribute:
8258     case OMPD_target_teams_distribute_simd:
8259     case OMPD_target:
8260     case OMPD_target_simd:
8261     case OMPD_target_parallel:
8262     case OMPD_cancel:
8263     case OMPD_parallel:
8264     case OMPD_parallel_sections:
8265     case OMPD_threadprivate:
8266     case OMPD_taskyield:
8267     case OMPD_barrier:
8268     case OMPD_taskwait:
8269     case OMPD_cancellation_point:
8270     case OMPD_flush:
8271     case OMPD_declare_reduction:
8272     case OMPD_declare_simd:
8273     case OMPD_declare_target:
8274     case OMPD_end_declare_target:
8275     case OMPD_simd:
8276     case OMPD_sections:
8277     case OMPD_section:
8278     case OMPD_single:
8279     case OMPD_master:
8280     case OMPD_critical:
8281     case OMPD_taskgroup:
8282     case OMPD_distribute:
8283     case OMPD_ordered:
8284     case OMPD_atomic:
8285     case OMPD_distribute_simd:
8286     case OMPD_target_teams:
8287       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8288     case OMPD_unknown:
8289       llvm_unreachable("Unknown OpenMP directive");
8290     }
8291     break;
8292   case OMPC_dist_schedule:
8293     switch (DKind) {
8294     case OMPD_teams_distribute_parallel_for:
8295     case OMPD_teams_distribute_parallel_for_simd:
8296     case OMPD_teams_distribute:
8297     case OMPD_teams_distribute_simd:
8298     case OMPD_target_teams_distribute_parallel_for:
8299     case OMPD_target_teams_distribute_parallel_for_simd:
8300     case OMPD_target_teams_distribute:
8301     case OMPD_target_teams_distribute_simd:
8302       CaptureRegion = OMPD_teams;
8303       break;
8304     case OMPD_distribute_parallel_for:
8305     case OMPD_distribute_parallel_for_simd:
8306     case OMPD_distribute:
8307     case OMPD_distribute_simd:
8308       // Do not capture thread_limit-clause expressions.
8309       break;
8310     case OMPD_parallel_for:
8311     case OMPD_parallel_for_simd:
8312     case OMPD_target_parallel_for_simd:
8313     case OMPD_target_parallel_for:
8314     case OMPD_task:
8315     case OMPD_taskloop:
8316     case OMPD_taskloop_simd:
8317     case OMPD_target_data:
8318     case OMPD_target_enter_data:
8319     case OMPD_target_exit_data:
8320     case OMPD_target_update:
8321     case OMPD_teams:
8322     case OMPD_target:
8323     case OMPD_target_simd:
8324     case OMPD_target_parallel:
8325     case OMPD_cancel:
8326     case OMPD_parallel:
8327     case OMPD_parallel_sections:
8328     case OMPD_threadprivate:
8329     case OMPD_taskyield:
8330     case OMPD_barrier:
8331     case OMPD_taskwait:
8332     case OMPD_cancellation_point:
8333     case OMPD_flush:
8334     case OMPD_declare_reduction:
8335     case OMPD_declare_simd:
8336     case OMPD_declare_target:
8337     case OMPD_end_declare_target:
8338     case OMPD_simd:
8339     case OMPD_for:
8340     case OMPD_for_simd:
8341     case OMPD_sections:
8342     case OMPD_section:
8343     case OMPD_single:
8344     case OMPD_master:
8345     case OMPD_critical:
8346     case OMPD_taskgroup:
8347     case OMPD_ordered:
8348     case OMPD_atomic:
8349     case OMPD_target_teams:
8350       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8351     case OMPD_unknown:
8352       llvm_unreachable("Unknown OpenMP directive");
8353     }
8354     break;
8355   case OMPC_device:
8356     switch (DKind) {
8357     case OMPD_target_update:
8358     case OMPD_target_enter_data:
8359     case OMPD_target_exit_data:
8360     case OMPD_target:
8361     case OMPD_target_simd:
8362     case OMPD_target_teams:
8363     case OMPD_target_parallel:
8364     case OMPD_target_teams_distribute:
8365     case OMPD_target_teams_distribute_simd:
8366     case OMPD_target_parallel_for:
8367     case OMPD_target_parallel_for_simd:
8368     case OMPD_target_teams_distribute_parallel_for:
8369     case OMPD_target_teams_distribute_parallel_for_simd:
8370       CaptureRegion = OMPD_task;
8371       break;
8372     case OMPD_target_data:
8373       // Do not capture device-clause expressions.
8374       break;
8375     case OMPD_teams_distribute_parallel_for:
8376     case OMPD_teams_distribute_parallel_for_simd:
8377     case OMPD_teams:
8378     case OMPD_teams_distribute:
8379     case OMPD_teams_distribute_simd:
8380     case OMPD_distribute_parallel_for:
8381     case OMPD_distribute_parallel_for_simd:
8382     case OMPD_task:
8383     case OMPD_taskloop:
8384     case OMPD_taskloop_simd:
8385     case OMPD_cancel:
8386     case OMPD_parallel:
8387     case OMPD_parallel_sections:
8388     case OMPD_parallel_for:
8389     case OMPD_parallel_for_simd:
8390     case OMPD_threadprivate:
8391     case OMPD_taskyield:
8392     case OMPD_barrier:
8393     case OMPD_taskwait:
8394     case OMPD_cancellation_point:
8395     case OMPD_flush:
8396     case OMPD_declare_reduction:
8397     case OMPD_declare_simd:
8398     case OMPD_declare_target:
8399     case OMPD_end_declare_target:
8400     case OMPD_simd:
8401     case OMPD_for:
8402     case OMPD_for_simd:
8403     case OMPD_sections:
8404     case OMPD_section:
8405     case OMPD_single:
8406     case OMPD_master:
8407     case OMPD_critical:
8408     case OMPD_taskgroup:
8409     case OMPD_distribute:
8410     case OMPD_ordered:
8411     case OMPD_atomic:
8412     case OMPD_distribute_simd:
8413       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8414     case OMPD_unknown:
8415       llvm_unreachable("Unknown OpenMP directive");
8416     }
8417     break;
8418   case OMPC_firstprivate:
8419   case OMPC_lastprivate:
8420   case OMPC_reduction:
8421   case OMPC_task_reduction:
8422   case OMPC_in_reduction:
8423   case OMPC_linear:
8424   case OMPC_default:
8425   case OMPC_proc_bind:
8426   case OMPC_final:
8427   case OMPC_safelen:
8428   case OMPC_simdlen:
8429   case OMPC_collapse:
8430   case OMPC_private:
8431   case OMPC_shared:
8432   case OMPC_aligned:
8433   case OMPC_copyin:
8434   case OMPC_copyprivate:
8435   case OMPC_ordered:
8436   case OMPC_nowait:
8437   case OMPC_untied:
8438   case OMPC_mergeable:
8439   case OMPC_threadprivate:
8440   case OMPC_flush:
8441   case OMPC_read:
8442   case OMPC_write:
8443   case OMPC_update:
8444   case OMPC_capture:
8445   case OMPC_seq_cst:
8446   case OMPC_depend:
8447   case OMPC_threads:
8448   case OMPC_simd:
8449   case OMPC_map:
8450   case OMPC_priority:
8451   case OMPC_grainsize:
8452   case OMPC_nogroup:
8453   case OMPC_num_tasks:
8454   case OMPC_hint:
8455   case OMPC_defaultmap:
8456   case OMPC_unknown:
8457   case OMPC_uniform:
8458   case OMPC_to:
8459   case OMPC_from:
8460   case OMPC_use_device_ptr:
8461   case OMPC_is_device_ptr:
8462     llvm_unreachable("Unexpected OpenMP clause.");
8463   }
8464   return CaptureRegion;
8465 }
8466 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)8467 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
8468                                      Expr *Condition, SourceLocation StartLoc,
8469                                      SourceLocation LParenLoc,
8470                                      SourceLocation NameModifierLoc,
8471                                      SourceLocation ColonLoc,
8472                                      SourceLocation EndLoc) {
8473   Expr *ValExpr = Condition;
8474   Stmt *HelperValStmt = nullptr;
8475   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8476   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8477       !Condition->isInstantiationDependent() &&
8478       !Condition->containsUnexpandedParameterPack()) {
8479     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8480     if (Val.isInvalid())
8481       return nullptr;
8482 
8483     ValExpr = Val.get();
8484 
8485     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8486     CaptureRegion =
8487         getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8488     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8489       ValExpr = MakeFullExpr(ValExpr).get();
8490       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8491       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8492       HelperValStmt = buildPreInits(Context, Captures);
8493     }
8494   }
8495 
8496   return new (Context)
8497       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8498                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8499 }
8500 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8501 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
8502                                         SourceLocation StartLoc,
8503                                         SourceLocation LParenLoc,
8504                                         SourceLocation EndLoc) {
8505   Expr *ValExpr = Condition;
8506   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8507       !Condition->isInstantiationDependent() &&
8508       !Condition->containsUnexpandedParameterPack()) {
8509     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8510     if (Val.isInvalid())
8511       return nullptr;
8512 
8513     ValExpr = MakeFullExpr(Val.get()).get();
8514   }
8515 
8516   return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8517 }
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)8518 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
8519                                                         Expr *Op) {
8520   if (!Op)
8521     return ExprError();
8522 
8523   class IntConvertDiagnoser : public ICEConvertDiagnoser {
8524   public:
8525     IntConvertDiagnoser()
8526         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8527     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8528                                          QualType T) override {
8529       return S.Diag(Loc, diag::err_omp_not_integral) << T;
8530     }
8531     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8532                                              QualType T) override {
8533       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8534     }
8535     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8536                                                QualType T,
8537                                                QualType ConvTy) override {
8538       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8539     }
8540     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8541                                            QualType ConvTy) override {
8542       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8543              << ConvTy->isEnumeralType() << ConvTy;
8544     }
8545     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8546                                             QualType T) override {
8547       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8548     }
8549     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8550                                         QualType ConvTy) override {
8551       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8552              << ConvTy->isEnumeralType() << ConvTy;
8553     }
8554     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8555                                              QualType) override {
8556       llvm_unreachable("conversion functions are permitted");
8557     }
8558   } ConvertDiagnoser;
8559   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8560 }
8561 
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive)8562 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8563                                       OpenMPClauseKind CKind,
8564                                       bool StrictlyPositive) {
8565   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8566       !ValExpr->isInstantiationDependent()) {
8567     SourceLocation Loc = ValExpr->getExprLoc();
8568     ExprResult Value =
8569         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8570     if (Value.isInvalid())
8571       return false;
8572 
8573     ValExpr = Value.get();
8574     // The expression must evaluate to a non-negative integer value.
8575     llvm::APSInt Result;
8576     if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8577         Result.isSigned() &&
8578         !((!StrictlyPositive && Result.isNonNegative()) ||
8579           (StrictlyPositive && Result.isStrictlyPositive()))) {
8580       SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8581           << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8582           << ValExpr->getSourceRange();
8583       return false;
8584     }
8585   }
8586   return true;
8587 }
8588 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8589 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
8590                                              SourceLocation StartLoc,
8591                                              SourceLocation LParenLoc,
8592                                              SourceLocation EndLoc) {
8593   Expr *ValExpr = NumThreads;
8594   Stmt *HelperValStmt = nullptr;
8595 
8596   // OpenMP [2.5, Restrictions]
8597   //  The num_threads expression must evaluate to a positive integer value.
8598   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8599                                  /*StrictlyPositive=*/true))
8600     return nullptr;
8601 
8602   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8603   OpenMPDirectiveKind CaptureRegion =
8604       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8605   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8606     ValExpr = MakeFullExpr(ValExpr).get();
8607     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8608     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8609     HelperValStmt = buildPreInits(Context, Captures);
8610   }
8611 
8612   return new (Context) OMPNumThreadsClause(
8613       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8614 }
8615 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)8616 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8617                                                        OpenMPClauseKind CKind,
8618                                                        bool StrictlyPositive) {
8619   if (!E)
8620     return ExprError();
8621   if (E->isValueDependent() || E->isTypeDependent() ||
8622       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
8623     return E;
8624   llvm::APSInt Result;
8625   ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8626   if (ICE.isInvalid())
8627     return ExprError();
8628   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8629       (!StrictlyPositive && !Result.isNonNegative())) {
8630     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8631         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8632         << E->getSourceRange();
8633     return ExprError();
8634   }
8635   if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8636     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8637         << E->getSourceRange();
8638     return ExprError();
8639   }
8640   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
8641     DSAStack->setAssociatedLoops(Result.getExtValue());
8642   else if (CKind == OMPC_ordered)
8643     DSAStack->setAssociatedLoops(Result.getExtValue());
8644   return ICE;
8645 }
8646 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8647 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
8648                                           SourceLocation LParenLoc,
8649                                           SourceLocation EndLoc) {
8650   // OpenMP [2.8.1, simd construct, Description]
8651   // The parameter of the safelen clause must be a constant
8652   // positive integer expression.
8653   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8654   if (Safelen.isInvalid())
8655     return nullptr;
8656   return new (Context)
8657       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
8658 }
8659 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8660 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
8661                                           SourceLocation LParenLoc,
8662                                           SourceLocation EndLoc) {
8663   // OpenMP [2.8.1, simd construct, Description]
8664   // The parameter of the simdlen clause must be a constant
8665   // positive integer expression.
8666   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8667   if (Simdlen.isInvalid())
8668     return nullptr;
8669   return new (Context)
8670       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
8671 }
8672 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8673 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
8674                                            SourceLocation StartLoc,
8675                                            SourceLocation LParenLoc,
8676                                            SourceLocation EndLoc) {
8677   // OpenMP [2.7.1, loop construct, Description]
8678   // OpenMP [2.8.1, simd construct, Description]
8679   // OpenMP [2.9.6, distribute construct, Description]
8680   // The parameter of the collapse clause must be a constant
8681   // positive integer expression.
8682   ExprResult NumForLoopsResult =
8683       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8684   if (NumForLoopsResult.isInvalid())
8685     return nullptr;
8686   return new (Context)
8687       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
8688 }
8689 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)8690 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
8691                                           SourceLocation EndLoc,
8692                                           SourceLocation LParenLoc,
8693                                           Expr *NumForLoops) {
8694   // OpenMP [2.7.1, loop construct, Description]
8695   // OpenMP [2.8.1, simd construct, Description]
8696   // OpenMP [2.9.6, distribute construct, Description]
8697   // The parameter of the ordered clause must be a constant
8698   // positive integer expression if any.
8699   if (NumForLoops && LParenLoc.isValid()) {
8700     ExprResult NumForLoopsResult =
8701         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8702     if (NumForLoopsResult.isInvalid())
8703       return nullptr;
8704     NumForLoops = NumForLoopsResult.get();
8705   } else {
8706     NumForLoops = nullptr;
8707   }
8708   auto *Clause = OMPOrderedClause::Create(
8709       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
8710       StartLoc, LParenLoc, EndLoc);
8711   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
8712   return Clause;
8713 }
8714 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8715 OMPClause *Sema::ActOnOpenMPSimpleClause(
8716     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
8717     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8718   OMPClause *Res = nullptr;
8719   switch (Kind) {
8720   case OMPC_default:
8721     Res =
8722         ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8723                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8724     break;
8725   case OMPC_proc_bind:
8726     Res = ActOnOpenMPProcBindClause(
8727         static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8728         LParenLoc, EndLoc);
8729     break;
8730   case OMPC_if:
8731   case OMPC_final:
8732   case OMPC_num_threads:
8733   case OMPC_safelen:
8734   case OMPC_simdlen:
8735   case OMPC_collapse:
8736   case OMPC_schedule:
8737   case OMPC_private:
8738   case OMPC_firstprivate:
8739   case OMPC_lastprivate:
8740   case OMPC_shared:
8741   case OMPC_reduction:
8742   case OMPC_task_reduction:
8743   case OMPC_in_reduction:
8744   case OMPC_linear:
8745   case OMPC_aligned:
8746   case OMPC_copyin:
8747   case OMPC_copyprivate:
8748   case OMPC_ordered:
8749   case OMPC_nowait:
8750   case OMPC_untied:
8751   case OMPC_mergeable:
8752   case OMPC_threadprivate:
8753   case OMPC_flush:
8754   case OMPC_read:
8755   case OMPC_write:
8756   case OMPC_update:
8757   case OMPC_capture:
8758   case OMPC_seq_cst:
8759   case OMPC_depend:
8760   case OMPC_device:
8761   case OMPC_threads:
8762   case OMPC_simd:
8763   case OMPC_map:
8764   case OMPC_num_teams:
8765   case OMPC_thread_limit:
8766   case OMPC_priority:
8767   case OMPC_grainsize:
8768   case OMPC_nogroup:
8769   case OMPC_num_tasks:
8770   case OMPC_hint:
8771   case OMPC_dist_schedule:
8772   case OMPC_defaultmap:
8773   case OMPC_unknown:
8774   case OMPC_uniform:
8775   case OMPC_to:
8776   case OMPC_from:
8777   case OMPC_use_device_ptr:
8778   case OMPC_is_device_ptr:
8779     llvm_unreachable("Clause is not allowed.");
8780   }
8781   return Res;
8782 }
8783 
8784 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)8785 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
8786                         ArrayRef<unsigned> Exclude = llvm::None) {
8787   SmallString<256> Buffer;
8788   llvm::raw_svector_ostream Out(Buffer);
8789   unsigned Bound = Last >= 2 ? Last - 2 : 0;
8790   unsigned Skipped = Exclude.size();
8791   auto S = Exclude.begin(), E = Exclude.end();
8792   for (unsigned I = First; I < Last; ++I) {
8793     if (std::find(S, E, I) != E) {
8794       --Skipped;
8795       continue;
8796     }
8797     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
8798     if (I == Bound - Skipped)
8799       Out << " or ";
8800     else if (I != Bound + 1 - Skipped)
8801       Out << ", ";
8802   }
8803   return Out.str();
8804 }
8805 
ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8806 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
8807                                           SourceLocation KindKwLoc,
8808                                           SourceLocation StartLoc,
8809                                           SourceLocation LParenLoc,
8810                                           SourceLocation EndLoc) {
8811   if (Kind == OMPC_DEFAULT_unknown) {
8812     static_assert(OMPC_DEFAULT_unknown > 0,
8813                   "OMPC_DEFAULT_unknown not greater than 0");
8814     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8815         << getListOfPossibleValues(OMPC_default, /*First=*/0,
8816                                    /*Last=*/OMPC_DEFAULT_unknown)
8817         << getOpenMPClauseName(OMPC_default);
8818     return nullptr;
8819   }
8820   switch (Kind) {
8821   case OMPC_DEFAULT_none:
8822     DSAStack->setDefaultDSANone(KindKwLoc);
8823     break;
8824   case OMPC_DEFAULT_shared:
8825     DSAStack->setDefaultDSAShared(KindKwLoc);
8826     break;
8827   case OMPC_DEFAULT_unknown:
8828     llvm_unreachable("Clause kind is not allowed.");
8829     break;
8830   }
8831   return new (Context)
8832       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8833 }
8834 
ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)8835 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
8836                                            SourceLocation KindKwLoc,
8837                                            SourceLocation StartLoc,
8838                                            SourceLocation LParenLoc,
8839                                            SourceLocation EndLoc) {
8840   if (Kind == OMPC_PROC_BIND_unknown) {
8841     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8842         << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
8843                                    /*Last=*/OMPC_PROC_BIND_unknown)
8844         << getOpenMPClauseName(OMPC_proc_bind);
8845     return nullptr;
8846   }
8847   return new (Context)
8848       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8849 }
8850 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)8851 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
8852     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
8853     SourceLocation StartLoc, SourceLocation LParenLoc,
8854     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
8855     SourceLocation EndLoc) {
8856   OMPClause *Res = nullptr;
8857   switch (Kind) {
8858   case OMPC_schedule:
8859     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8860     assert(Argument.size() == NumberOfElements &&
8861            ArgumentLoc.size() == NumberOfElements);
8862     Res = ActOnOpenMPScheduleClause(
8863         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8864         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8865         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8866         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8867         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8868     break;
8869   case OMPC_if:
8870     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8871     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8872                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8873                               DelimLoc, EndLoc);
8874     break;
8875   case OMPC_dist_schedule:
8876     Res = ActOnOpenMPDistScheduleClause(
8877         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8878         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8879     break;
8880   case OMPC_defaultmap:
8881     enum { Modifier, DefaultmapKind };
8882     Res = ActOnOpenMPDefaultmapClause(
8883         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
8884         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8885         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8886         EndLoc);
8887     break;
8888   case OMPC_final:
8889   case OMPC_num_threads:
8890   case OMPC_safelen:
8891   case OMPC_simdlen:
8892   case OMPC_collapse:
8893   case OMPC_default:
8894   case OMPC_proc_bind:
8895   case OMPC_private:
8896   case OMPC_firstprivate:
8897   case OMPC_lastprivate:
8898   case OMPC_shared:
8899   case OMPC_reduction:
8900   case OMPC_task_reduction:
8901   case OMPC_in_reduction:
8902   case OMPC_linear:
8903   case OMPC_aligned:
8904   case OMPC_copyin:
8905   case OMPC_copyprivate:
8906   case OMPC_ordered:
8907   case OMPC_nowait:
8908   case OMPC_untied:
8909   case OMPC_mergeable:
8910   case OMPC_threadprivate:
8911   case OMPC_flush:
8912   case OMPC_read:
8913   case OMPC_write:
8914   case OMPC_update:
8915   case OMPC_capture:
8916   case OMPC_seq_cst:
8917   case OMPC_depend:
8918   case OMPC_device:
8919   case OMPC_threads:
8920   case OMPC_simd:
8921   case OMPC_map:
8922   case OMPC_num_teams:
8923   case OMPC_thread_limit:
8924   case OMPC_priority:
8925   case OMPC_grainsize:
8926   case OMPC_nogroup:
8927   case OMPC_num_tasks:
8928   case OMPC_hint:
8929   case OMPC_unknown:
8930   case OMPC_uniform:
8931   case OMPC_to:
8932   case OMPC_from:
8933   case OMPC_use_device_ptr:
8934   case OMPC_is_device_ptr:
8935     llvm_unreachable("Clause is not allowed.");
8936   }
8937   return Res;
8938 }
8939 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)8940 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
8941                                    OpenMPScheduleClauseModifier M2,
8942                                    SourceLocation M1Loc, SourceLocation M2Loc) {
8943   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
8944     SmallVector<unsigned, 2> Excluded;
8945     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
8946       Excluded.push_back(M2);
8947     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8948       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8949     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8950       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8951     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8952         << getListOfPossibleValues(OMPC_schedule,
8953                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
8954                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8955                                    Excluded)
8956         << getOpenMPClauseName(OMPC_schedule);
8957     return true;
8958   }
8959   return false;
8960 }
8961 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)8962 OMPClause *Sema::ActOnOpenMPScheduleClause(
8963     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
8964     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
8965     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
8966     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
8967   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
8968       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
8969     return nullptr;
8970   // OpenMP, 2.7.1, Loop Construct, Restrictions
8971   // Either the monotonic modifier or the nonmonotonic modifier can be specified
8972   // but not both.
8973   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
8974       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8975        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8976       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8977        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8978     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8979         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
8980         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
8981     return nullptr;
8982   }
8983   if (Kind == OMPC_SCHEDULE_unknown) {
8984     std::string Values;
8985     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
8986       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
8987       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8988                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8989                                        Exclude);
8990     } else {
8991       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8992                                        /*Last=*/OMPC_SCHEDULE_unknown);
8993     }
8994     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8995         << Values << getOpenMPClauseName(OMPC_schedule);
8996     return nullptr;
8997   }
8998   // OpenMP, 2.7.1, Loop Construct, Restrictions
8999   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
9000   // schedule(guided).
9001   if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9002        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9003       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9004     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9005          diag::err_omp_schedule_nonmonotonic_static);
9006     return nullptr;
9007   }
9008   Expr *ValExpr = ChunkSize;
9009   Stmt *HelperValStmt = nullptr;
9010   if (ChunkSize) {
9011     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
9012         !ChunkSize->isInstantiationDependent() &&
9013         !ChunkSize->containsUnexpandedParameterPack()) {
9014       SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
9015       ExprResult Val =
9016           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9017       if (Val.isInvalid())
9018         return nullptr;
9019 
9020       ValExpr = Val.get();
9021 
9022       // OpenMP [2.7.1, Restrictions]
9023       //  chunk_size must be a loop invariant integer expression with a positive
9024       //  value.
9025       llvm::APSInt Result;
9026       if (ValExpr->isIntegerConstantExpr(Result, Context)) {
9027         if (Result.isSigned() && !Result.isStrictlyPositive()) {
9028           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9029               << "schedule" << 1 << ChunkSize->getSourceRange();
9030           return nullptr;
9031         }
9032       } else if (getOpenMPCaptureRegionForClause(
9033                      DSAStack->getCurrentDirective(), OMPC_schedule) !=
9034                      OMPD_unknown &&
9035                  !CurContext->isDependentContext()) {
9036         ValExpr = MakeFullExpr(ValExpr).get();
9037         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9038         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9039         HelperValStmt = buildPreInits(Context, Captures);
9040       }
9041     }
9042   }
9043 
9044   return new (Context)
9045       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
9046                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9047 }
9048 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)9049 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
9050                                    SourceLocation StartLoc,
9051                                    SourceLocation EndLoc) {
9052   OMPClause *Res = nullptr;
9053   switch (Kind) {
9054   case OMPC_ordered:
9055     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9056     break;
9057   case OMPC_nowait:
9058     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9059     break;
9060   case OMPC_untied:
9061     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9062     break;
9063   case OMPC_mergeable:
9064     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9065     break;
9066   case OMPC_read:
9067     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9068     break;
9069   case OMPC_write:
9070     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9071     break;
9072   case OMPC_update:
9073     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9074     break;
9075   case OMPC_capture:
9076     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9077     break;
9078   case OMPC_seq_cst:
9079     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9080     break;
9081   case OMPC_threads:
9082     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9083     break;
9084   case OMPC_simd:
9085     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9086     break;
9087   case OMPC_nogroup:
9088     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9089     break;
9090   case OMPC_if:
9091   case OMPC_final:
9092   case OMPC_num_threads:
9093   case OMPC_safelen:
9094   case OMPC_simdlen:
9095   case OMPC_collapse:
9096   case OMPC_schedule:
9097   case OMPC_private:
9098   case OMPC_firstprivate:
9099   case OMPC_lastprivate:
9100   case OMPC_shared:
9101   case OMPC_reduction:
9102   case OMPC_task_reduction:
9103   case OMPC_in_reduction:
9104   case OMPC_linear:
9105   case OMPC_aligned:
9106   case OMPC_copyin:
9107   case OMPC_copyprivate:
9108   case OMPC_default:
9109   case OMPC_proc_bind:
9110   case OMPC_threadprivate:
9111   case OMPC_flush:
9112   case OMPC_depend:
9113   case OMPC_device:
9114   case OMPC_map:
9115   case OMPC_num_teams:
9116   case OMPC_thread_limit:
9117   case OMPC_priority:
9118   case OMPC_grainsize:
9119   case OMPC_num_tasks:
9120   case OMPC_hint:
9121   case OMPC_dist_schedule:
9122   case OMPC_defaultmap:
9123   case OMPC_unknown:
9124   case OMPC_uniform:
9125   case OMPC_to:
9126   case OMPC_from:
9127   case OMPC_use_device_ptr:
9128   case OMPC_is_device_ptr:
9129     llvm_unreachable("Clause is not allowed.");
9130   }
9131   return Res;
9132 }
9133 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)9134 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
9135                                          SourceLocation EndLoc) {
9136   DSAStack->setNowaitRegion();
9137   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
9138 }
9139 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)9140 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
9141                                          SourceLocation EndLoc) {
9142   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
9143 }
9144 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)9145 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
9146                                             SourceLocation EndLoc) {
9147   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
9148 }
9149 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)9150 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
9151                                        SourceLocation EndLoc) {
9152   return new (Context) OMPReadClause(StartLoc, EndLoc);
9153 }
9154 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)9155 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
9156                                         SourceLocation EndLoc) {
9157   return new (Context) OMPWriteClause(StartLoc, EndLoc);
9158 }
9159 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)9160 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
9161                                          SourceLocation EndLoc) {
9162   return new (Context) OMPUpdateClause(StartLoc, EndLoc);
9163 }
9164 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)9165 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
9166                                           SourceLocation EndLoc) {
9167   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
9168 }
9169 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)9170 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
9171                                          SourceLocation EndLoc) {
9172   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
9173 }
9174 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)9175 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
9176                                           SourceLocation EndLoc) {
9177   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
9178 }
9179 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)9180 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
9181                                        SourceLocation EndLoc) {
9182   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
9183 }
9184 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)9185 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
9186                                           SourceLocation EndLoc) {
9187   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
9188 }
9189 
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,Expr * TailExpr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,OpenMPDependClauseKind DepKind,OpenMPLinearClauseKind LinKind,OpenMPMapClauseKind MapTypeModifier,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation DepLinMapLoc)9190 OMPClause *Sema::ActOnOpenMPVarListClause(
9191     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
9192     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
9193     SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
9194     const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
9195     OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
9196     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
9197     SourceLocation DepLinMapLoc) {
9198   OMPClause *Res = nullptr;
9199   switch (Kind) {
9200   case OMPC_private:
9201     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9202     break;
9203   case OMPC_firstprivate:
9204     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9205     break;
9206   case OMPC_lastprivate:
9207     Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9208     break;
9209   case OMPC_shared:
9210     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9211     break;
9212   case OMPC_reduction:
9213     Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9214                                      EndLoc, ReductionIdScopeSpec, ReductionId);
9215     break;
9216   case OMPC_task_reduction:
9217     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9218                                          EndLoc, ReductionIdScopeSpec,
9219                                          ReductionId);
9220     break;
9221   case OMPC_in_reduction:
9222     Res =
9223         ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9224                                      EndLoc, ReductionIdScopeSpec, ReductionId);
9225     break;
9226   case OMPC_linear:
9227     Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9228                                   LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9229     break;
9230   case OMPC_aligned:
9231     Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9232                                    ColonLoc, EndLoc);
9233     break;
9234   case OMPC_copyin:
9235     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9236     break;
9237   case OMPC_copyprivate:
9238     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9239     break;
9240   case OMPC_flush:
9241     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9242     break;
9243   case OMPC_depend:
9244     Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9245                                   StartLoc, LParenLoc, EndLoc);
9246     break;
9247   case OMPC_map:
9248     Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
9249                                DepLinMapLoc, ColonLoc, VarList, StartLoc,
9250                                LParenLoc, EndLoc);
9251     break;
9252   case OMPC_to:
9253     Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9254     break;
9255   case OMPC_from:
9256     Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9257     break;
9258   case OMPC_use_device_ptr:
9259     Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9260     break;
9261   case OMPC_is_device_ptr:
9262     Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9263     break;
9264   case OMPC_if:
9265   case OMPC_final:
9266   case OMPC_num_threads:
9267   case OMPC_safelen:
9268   case OMPC_simdlen:
9269   case OMPC_collapse:
9270   case OMPC_default:
9271   case OMPC_proc_bind:
9272   case OMPC_schedule:
9273   case OMPC_ordered:
9274   case OMPC_nowait:
9275   case OMPC_untied:
9276   case OMPC_mergeable:
9277   case OMPC_threadprivate:
9278   case OMPC_read:
9279   case OMPC_write:
9280   case OMPC_update:
9281   case OMPC_capture:
9282   case OMPC_seq_cst:
9283   case OMPC_device:
9284   case OMPC_threads:
9285   case OMPC_simd:
9286   case OMPC_num_teams:
9287   case OMPC_thread_limit:
9288   case OMPC_priority:
9289   case OMPC_grainsize:
9290   case OMPC_nogroup:
9291   case OMPC_num_tasks:
9292   case OMPC_hint:
9293   case OMPC_dist_schedule:
9294   case OMPC_defaultmap:
9295   case OMPC_unknown:
9296   case OMPC_uniform:
9297     llvm_unreachable("Clause is not allowed.");
9298   }
9299   return Res;
9300 }
9301 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)9302 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
9303                                        ExprObjectKind OK, SourceLocation Loc) {
9304   ExprResult Res = BuildDeclRefExpr(
9305       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
9306   if (!Res.isUsable())
9307     return ExprError();
9308   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
9309     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
9310     if (!Res.isUsable())
9311       return ExprError();
9312   }
9313   if (VK != VK_LValue && Res.get()->isGLValue()) {
9314     Res = DefaultLvalueConversion(Res.get());
9315     if (!Res.isUsable())
9316       return ExprError();
9317   }
9318   return Res;
9319 }
9320 
9321 static std::pair<ValueDecl *, bool>
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection=false)9322 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
9323                SourceRange &ERange, bool AllowArraySection = false) {
9324   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
9325       RefExpr->containsUnexpandedParameterPack())
9326     return std::make_pair(nullptr, true);
9327 
9328   // OpenMP [3.1, C/C++]
9329   //  A list item is a variable name.
9330   // OpenMP  [2.9.3.3, Restrictions, p.1]
9331   //  A variable that is part of another variable (as an array or
9332   //  structure element) cannot appear in a private clause.
9333   RefExpr = RefExpr->IgnoreParens();
9334   enum {
9335     NoArrayExpr = -1,
9336     ArraySubscript = 0,
9337     OMPArraySection = 1
9338   } IsArrayExpr = NoArrayExpr;
9339   if (AllowArraySection) {
9340     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9341       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
9342       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9343         Base = TempASE->getBase()->IgnoreParenImpCasts();
9344       RefExpr = Base;
9345       IsArrayExpr = ArraySubscript;
9346     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9347       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9348       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9349         Base = TempOASE->getBase()->IgnoreParenImpCasts();
9350       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9351         Base = TempASE->getBase()->IgnoreParenImpCasts();
9352       RefExpr = Base;
9353       IsArrayExpr = OMPArraySection;
9354     }
9355   }
9356   ELoc = RefExpr->getExprLoc();
9357   ERange = RefExpr->getSourceRange();
9358   RefExpr = RefExpr->IgnoreParenImpCasts();
9359   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9360   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9361   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9362       (S.getCurrentThisType().isNull() || !ME ||
9363        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9364        !isa<FieldDecl>(ME->getMemberDecl()))) {
9365     if (IsArrayExpr != NoArrayExpr) {
9366       S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9367                                                          << ERange;
9368     } else {
9369       S.Diag(ELoc,
9370              AllowArraySection
9371                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
9372                  : diag::err_omp_expected_var_name_member_expr)
9373           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9374     }
9375     return std::make_pair(nullptr, false);
9376   }
9377   return std::make_pair(
9378       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9379 }
9380 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9381 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
9382                                           SourceLocation StartLoc,
9383                                           SourceLocation LParenLoc,
9384                                           SourceLocation EndLoc) {
9385   SmallVector<Expr *, 8> Vars;
9386   SmallVector<Expr *, 8> PrivateCopies;
9387   for (Expr *RefExpr : VarList) {
9388     assert(RefExpr && "NULL expr in OpenMP private clause.");
9389     SourceLocation ELoc;
9390     SourceRange ERange;
9391     Expr *SimpleRefExpr = RefExpr;
9392     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9393     if (Res.second) {
9394       // It will be analyzed later.
9395       Vars.push_back(RefExpr);
9396       PrivateCopies.push_back(nullptr);
9397     }
9398     ValueDecl *D = Res.first;
9399     if (!D)
9400       continue;
9401 
9402     QualType Type = D->getType();
9403     auto *VD = dyn_cast<VarDecl>(D);
9404 
9405     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9406     //  A variable that appears in a private clause must not have an incomplete
9407     //  type or a reference type.
9408     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9409       continue;
9410     Type = Type.getNonReferenceType();
9411 
9412     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9413     // in a Construct]
9414     //  Variables with the predetermined data-sharing attributes may not be
9415     //  listed in data-sharing attributes clauses, except for the cases
9416     //  listed below. For these exceptions only, listing a predetermined
9417     //  variable in a data-sharing attribute clause is allowed and overrides
9418     //  the variable's predetermined data-sharing attributes.
9419     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9420     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9421       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9422                                           << getOpenMPClauseName(OMPC_private);
9423       reportOriginalDsa(*this, DSAStack, D, DVar);
9424       continue;
9425     }
9426 
9427     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9428     // Variably modified types are not supported for tasks.
9429     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9430         isOpenMPTaskingDirective(CurrDir)) {
9431       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9432           << getOpenMPClauseName(OMPC_private) << Type
9433           << getOpenMPDirectiveName(CurrDir);
9434       bool IsDecl =
9435           !VD ||
9436           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9437       Diag(D->getLocation(),
9438            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9439           << D;
9440       continue;
9441     }
9442 
9443     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9444     // A list item cannot appear in both a map clause and a data-sharing
9445     // attribute clause on the same construct
9446     if (isOpenMPTargetExecutionDirective(CurrDir)) {
9447       OpenMPClauseKind ConflictKind;
9448       if (DSAStack->checkMappableExprComponentListsForDecl(
9449               VD, /*CurrentRegionOnly=*/true,
9450               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9451                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
9452                 ConflictKind = WhereFoundClauseKind;
9453                 return true;
9454               })) {
9455         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9456             << getOpenMPClauseName(OMPC_private)
9457             << getOpenMPClauseName(ConflictKind)
9458             << getOpenMPDirectiveName(CurrDir);
9459         reportOriginalDsa(*this, DSAStack, D, DVar);
9460         continue;
9461       }
9462     }
9463 
9464     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9465     //  A variable of class type (or array thereof) that appears in a private
9466     //  clause requires an accessible, unambiguous default constructor for the
9467     //  class type.
9468     // Generate helper private variable and initialize it with the default
9469     // value. The address of the original variable is replaced by the address of
9470     // the new private variable in CodeGen. This new variable is not added to
9471     // IdResolver, so the code in the OpenMP region uses original variable for
9472     // proper diagnostics.
9473     Type = Type.getUnqualifiedType();
9474     VarDecl *VDPrivate =
9475         buildVarDecl(*this, ELoc, Type, D->getName(),
9476                      D->hasAttrs() ? &D->getAttrs() : nullptr,
9477                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9478     ActOnUninitializedDecl(VDPrivate);
9479     if (VDPrivate->isInvalidDecl())
9480       continue;
9481     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9482         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9483 
9484     DeclRefExpr *Ref = nullptr;
9485     if (!VD && !CurContext->isDependentContext())
9486       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9487     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9488     Vars.push_back((VD || CurContext->isDependentContext())
9489                        ? RefExpr->IgnoreParens()
9490                        : Ref);
9491     PrivateCopies.push_back(VDPrivateRefExpr);
9492   }
9493 
9494   if (Vars.empty())
9495     return nullptr;
9496 
9497   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9498                                   PrivateCopies);
9499 }
9500 
9501 namespace {
9502 class DiagsUninitializedSeveretyRAII {
9503 private:
9504   DiagnosticsEngine &Diags;
9505   SourceLocation SavedLoc;
9506   bool IsIgnored = false;
9507 
9508 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)9509   DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9510                                  bool IsIgnored)
9511       : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9512     if (!IsIgnored) {
9513       Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9514                         /*Map*/ diag::Severity::Ignored, Loc);
9515     }
9516   }
~DiagsUninitializedSeveretyRAII()9517   ~DiagsUninitializedSeveretyRAII() {
9518     if (!IsIgnored)
9519       Diags.popMappings(SavedLoc);
9520   }
9521 };
9522 }
9523 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9524 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
9525                                                SourceLocation StartLoc,
9526                                                SourceLocation LParenLoc,
9527                                                SourceLocation EndLoc) {
9528   SmallVector<Expr *, 8> Vars;
9529   SmallVector<Expr *, 8> PrivateCopies;
9530   SmallVector<Expr *, 8> Inits;
9531   SmallVector<Decl *, 4> ExprCaptures;
9532   bool IsImplicitClause =
9533       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9534   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
9535 
9536   for (Expr *RefExpr : VarList) {
9537     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9538     SourceLocation ELoc;
9539     SourceRange ERange;
9540     Expr *SimpleRefExpr = RefExpr;
9541     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9542     if (Res.second) {
9543       // It will be analyzed later.
9544       Vars.push_back(RefExpr);
9545       PrivateCopies.push_back(nullptr);
9546       Inits.push_back(nullptr);
9547     }
9548     ValueDecl *D = Res.first;
9549     if (!D)
9550       continue;
9551 
9552     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9553     QualType Type = D->getType();
9554     auto *VD = dyn_cast<VarDecl>(D);
9555 
9556     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9557     //  A variable that appears in a private clause must not have an incomplete
9558     //  type or a reference type.
9559     if (RequireCompleteType(ELoc, Type,
9560                             diag::err_omp_firstprivate_incomplete_type))
9561       continue;
9562     Type = Type.getNonReferenceType();
9563 
9564     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
9565     //  A variable of class type (or array thereof) that appears in a private
9566     //  clause requires an accessible, unambiguous copy constructor for the
9567     //  class type.
9568     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9569 
9570     // If an implicit firstprivate variable found it was checked already.
9571     DSAStackTy::DSAVarData TopDVar;
9572     if (!IsImplicitClause) {
9573       DSAStackTy::DSAVarData DVar =
9574           DSAStack->getTopDSA(D, /*FromParent=*/false);
9575       TopDVar = DVar;
9576       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9577       bool IsConstant = ElemType.isConstant(Context);
9578       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
9579       //  A list item that specifies a given variable may not appear in more
9580       // than one clause on the same directive, except that a variable may be
9581       //  specified in both firstprivate and lastprivate clauses.
9582       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9583       // A list item may appear in a firstprivate or lastprivate clause but not
9584       // both.
9585       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9586           (isOpenMPDistributeDirective(CurrDir) ||
9587            DVar.CKind != OMPC_lastprivate) &&
9588           DVar.RefExpr) {
9589         Diag(ELoc, diag::err_omp_wrong_dsa)
9590             << getOpenMPClauseName(DVar.CKind)
9591             << getOpenMPClauseName(OMPC_firstprivate);
9592         reportOriginalDsa(*this, DSAStack, D, DVar);
9593         continue;
9594       }
9595 
9596       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9597       // in a Construct]
9598       //  Variables with the predetermined data-sharing attributes may not be
9599       //  listed in data-sharing attributes clauses, except for the cases
9600       //  listed below. For these exceptions only, listing a predetermined
9601       //  variable in a data-sharing attribute clause is allowed and overrides
9602       //  the variable's predetermined data-sharing attributes.
9603       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9604       // in a Construct, C/C++, p.2]
9605       //  Variables with const-qualified type having no mutable member may be
9606       //  listed in a firstprivate clause, even if they are static data members.
9607       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9608           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
9609         Diag(ELoc, diag::err_omp_wrong_dsa)
9610             << getOpenMPClauseName(DVar.CKind)
9611             << getOpenMPClauseName(OMPC_firstprivate);
9612         reportOriginalDsa(*this, DSAStack, D, DVar);
9613         continue;
9614       }
9615 
9616       // OpenMP [2.9.3.4, Restrictions, p.2]
9617       //  A list item that is private within a parallel region must not appear
9618       //  in a firstprivate clause on a worksharing construct if any of the
9619       //  worksharing regions arising from the worksharing construct ever bind
9620       //  to any of the parallel regions arising from the parallel construct.
9621       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9622       // A list item that is private within a teams region must not appear in a
9623       // firstprivate clause on a distribute construct if any of the distribute
9624       // regions arising from the distribute construct ever bind to any of the
9625       // teams regions arising from the teams construct.
9626       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9627       // A list item that appears in a reduction clause of a teams construct
9628       // must not appear in a firstprivate clause on a distribute construct if
9629       // any of the distribute regions arising from the distribute construct
9630       // ever bind to any of the teams regions arising from the teams construct.
9631       if ((isOpenMPWorksharingDirective(CurrDir) ||
9632            isOpenMPDistributeDirective(CurrDir)) &&
9633           !isOpenMPParallelDirective(CurrDir) &&
9634           !isOpenMPTeamsDirective(CurrDir)) {
9635         DVar = DSAStack->getImplicitDSA(D, true);
9636         if (DVar.CKind != OMPC_shared &&
9637             (isOpenMPParallelDirective(DVar.DKind) ||
9638              isOpenMPTeamsDirective(DVar.DKind) ||
9639              DVar.DKind == OMPD_unknown)) {
9640           Diag(ELoc, diag::err_omp_required_access)
9641               << getOpenMPClauseName(OMPC_firstprivate)
9642               << getOpenMPClauseName(OMPC_shared);
9643           reportOriginalDsa(*this, DSAStack, D, DVar);
9644           continue;
9645         }
9646       }
9647       // OpenMP [2.9.3.4, Restrictions, p.3]
9648       //  A list item that appears in a reduction clause of a parallel construct
9649       //  must not appear in a firstprivate clause on a worksharing or task
9650       //  construct if any of the worksharing or task regions arising from the
9651       //  worksharing or task construct ever bind to any of the parallel regions
9652       //  arising from the parallel construct.
9653       // OpenMP [2.9.3.4, Restrictions, p.4]
9654       //  A list item that appears in a reduction clause in worksharing
9655       //  construct must not appear in a firstprivate clause in a task construct
9656       //  encountered during execution of any of the worksharing regions arising
9657       //  from the worksharing construct.
9658       if (isOpenMPTaskingDirective(CurrDir)) {
9659         DVar = DSAStack->hasInnermostDSA(
9660             D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
9661             [](OpenMPDirectiveKind K) {
9662               return isOpenMPParallelDirective(K) ||
9663                      isOpenMPWorksharingDirective(K) ||
9664                      isOpenMPTeamsDirective(K);
9665             },
9666             /*FromParent=*/true);
9667         if (DVar.CKind == OMPC_reduction &&
9668             (isOpenMPParallelDirective(DVar.DKind) ||
9669              isOpenMPWorksharingDirective(DVar.DKind) ||
9670              isOpenMPTeamsDirective(DVar.DKind))) {
9671           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9672               << getOpenMPDirectiveName(DVar.DKind);
9673           reportOriginalDsa(*this, DSAStack, D, DVar);
9674           continue;
9675         }
9676       }
9677 
9678       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9679       // A list item cannot appear in both a map clause and a data-sharing
9680       // attribute clause on the same construct
9681       if (isOpenMPTargetExecutionDirective(CurrDir)) {
9682         OpenMPClauseKind ConflictKind;
9683         if (DSAStack->checkMappableExprComponentListsForDecl(
9684                 VD, /*CurrentRegionOnly=*/true,
9685                 [&ConflictKind](
9686                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
9687                     OpenMPClauseKind WhereFoundClauseKind) {
9688                   ConflictKind = WhereFoundClauseKind;
9689                   return true;
9690                 })) {
9691           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9692               << getOpenMPClauseName(OMPC_firstprivate)
9693               << getOpenMPClauseName(ConflictKind)
9694               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9695           reportOriginalDsa(*this, DSAStack, D, DVar);
9696           continue;
9697         }
9698       }
9699     }
9700 
9701     // Variably modified types are not supported for tasks.
9702     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9703         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
9704       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9705           << getOpenMPClauseName(OMPC_firstprivate) << Type
9706           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9707       bool IsDecl =
9708           !VD ||
9709           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9710       Diag(D->getLocation(),
9711            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9712           << D;
9713       continue;
9714     }
9715 
9716     Type = Type.getUnqualifiedType();
9717     VarDecl *VDPrivate =
9718         buildVarDecl(*this, ELoc, Type, D->getName(),
9719                      D->hasAttrs() ? &D->getAttrs() : nullptr,
9720                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9721     // Generate helper private variable and initialize it with the value of the
9722     // original variable. The address of the original variable is replaced by
9723     // the address of the new private variable in the CodeGen. This new variable
9724     // is not added to IdResolver, so the code in the OpenMP region uses
9725     // original variable for proper diagnostics and variable capturing.
9726     Expr *VDInitRefExpr = nullptr;
9727     // For arrays generate initializer for single element and replace it by the
9728     // original array element in CodeGen.
9729     if (Type->isArrayType()) {
9730       VarDecl *VDInit =
9731           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
9732       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
9733       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
9734       ElemType = ElemType.getUnqualifiedType();
9735       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
9736                                          ".firstprivate.temp");
9737       InitializedEntity Entity =
9738           InitializedEntity::InitializeVariable(VDInitTemp);
9739       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
9740 
9741       InitializationSequence InitSeq(*this, Entity, Kind, Init);
9742       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
9743       if (Result.isInvalid())
9744         VDPrivate->setInvalidDecl();
9745       else
9746         VDPrivate->setInit(Result.getAs<Expr>());
9747       // Remove temp variable declaration.
9748       Context.Deallocate(VDInitTemp);
9749     } else {
9750       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
9751                                      ".firstprivate.temp");
9752       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
9753                                        RefExpr->getExprLoc());
9754       AddInitializerToDecl(VDPrivate,
9755                            DefaultLvalueConversion(VDInitRefExpr).get(),
9756                            /*DirectInit=*/false);
9757     }
9758     if (VDPrivate->isInvalidDecl()) {
9759       if (IsImplicitClause) {
9760         Diag(RefExpr->getExprLoc(),
9761              diag::note_omp_task_predetermined_firstprivate_here);
9762       }
9763       continue;
9764     }
9765     CurContext->addDecl(VDPrivate);
9766     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9767         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9768         RefExpr->getExprLoc());
9769     DeclRefExpr *Ref = nullptr;
9770     if (!VD && !CurContext->isDependentContext()) {
9771       if (TopDVar.CKind == OMPC_lastprivate) {
9772         Ref = TopDVar.PrivateCopy;
9773       } else {
9774         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9775         if (!isOpenMPCapturedDecl(D))
9776           ExprCaptures.push_back(Ref->getDecl());
9777       }
9778     }
9779     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9780     Vars.push_back((VD || CurContext->isDependentContext())
9781                        ? RefExpr->IgnoreParens()
9782                        : Ref);
9783     PrivateCopies.push_back(VDPrivateRefExpr);
9784     Inits.push_back(VDInitRefExpr);
9785   }
9786 
9787   if (Vars.empty())
9788     return nullptr;
9789 
9790   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9791                                        Vars, PrivateCopies, Inits,
9792                                        buildPreInits(Context, ExprCaptures));
9793 }
9794 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9795 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
9796                                               SourceLocation StartLoc,
9797                                               SourceLocation LParenLoc,
9798                                               SourceLocation EndLoc) {
9799   SmallVector<Expr *, 8> Vars;
9800   SmallVector<Expr *, 8> SrcExprs;
9801   SmallVector<Expr *, 8> DstExprs;
9802   SmallVector<Expr *, 8> AssignmentOps;
9803   SmallVector<Decl *, 4> ExprCaptures;
9804   SmallVector<Expr *, 4> ExprPostUpdates;
9805   for (Expr *RefExpr : VarList) {
9806     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9807     SourceLocation ELoc;
9808     SourceRange ERange;
9809     Expr *SimpleRefExpr = RefExpr;
9810     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9811     if (Res.second) {
9812       // It will be analyzed later.
9813       Vars.push_back(RefExpr);
9814       SrcExprs.push_back(nullptr);
9815       DstExprs.push_back(nullptr);
9816       AssignmentOps.push_back(nullptr);
9817     }
9818     ValueDecl *D = Res.first;
9819     if (!D)
9820       continue;
9821 
9822     QualType Type = D->getType();
9823     auto *VD = dyn_cast<VarDecl>(D);
9824 
9825     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
9826     //  A variable that appears in a lastprivate clause must not have an
9827     //  incomplete type or a reference type.
9828     if (RequireCompleteType(ELoc, Type,
9829                             diag::err_omp_lastprivate_incomplete_type))
9830       continue;
9831     Type = Type.getNonReferenceType();
9832 
9833     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9834     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9835     // in a Construct]
9836     //  Variables with the predetermined data-sharing attributes may not be
9837     //  listed in data-sharing attributes clauses, except for the cases
9838     //  listed below.
9839     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9840     // A list item may appear in a firstprivate or lastprivate clause but not
9841     // both.
9842     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9843     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9844         (isOpenMPDistributeDirective(CurrDir) ||
9845          DVar.CKind != OMPC_firstprivate) &&
9846         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
9847       Diag(ELoc, diag::err_omp_wrong_dsa)
9848           << getOpenMPClauseName(DVar.CKind)
9849           << getOpenMPClauseName(OMPC_lastprivate);
9850       reportOriginalDsa(*this, DSAStack, D, DVar);
9851       continue;
9852     }
9853 
9854     // OpenMP [2.14.3.5, Restrictions, p.2]
9855     // A list item that is private within a parallel region, or that appears in
9856     // the reduction clause of a parallel construct, must not appear in a
9857     // lastprivate clause on a worksharing construct if any of the corresponding
9858     // worksharing regions ever binds to any of the corresponding parallel
9859     // regions.
9860     DSAStackTy::DSAVarData TopDVar = DVar;
9861     if (isOpenMPWorksharingDirective(CurrDir) &&
9862         !isOpenMPParallelDirective(CurrDir) &&
9863         !isOpenMPTeamsDirective(CurrDir)) {
9864       DVar = DSAStack->getImplicitDSA(D, true);
9865       if (DVar.CKind != OMPC_shared) {
9866         Diag(ELoc, diag::err_omp_required_access)
9867             << getOpenMPClauseName(OMPC_lastprivate)
9868             << getOpenMPClauseName(OMPC_shared);
9869         reportOriginalDsa(*this, DSAStack, D, DVar);
9870         continue;
9871       }
9872     }
9873 
9874     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
9875     //  A variable of class type (or array thereof) that appears in a
9876     //  lastprivate clause requires an accessible, unambiguous default
9877     //  constructor for the class type, unless the list item is also specified
9878     //  in a firstprivate clause.
9879     //  A variable of class type (or array thereof) that appears in a
9880     //  lastprivate clause requires an accessible, unambiguous copy assignment
9881     //  operator for the class type.
9882     Type = Context.getBaseElementType(Type).getNonReferenceType();
9883     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
9884                                   Type.getUnqualifiedType(), ".lastprivate.src",
9885                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
9886     DeclRefExpr *PseudoSrcExpr =
9887         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
9888     VarDecl *DstVD =
9889         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
9890                      D->hasAttrs() ? &D->getAttrs() : nullptr);
9891     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
9892     // For arrays generate assignment operation for single element and replace
9893     // it by the original array element in CodeGen.
9894     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
9895                                          PseudoDstExpr, PseudoSrcExpr);
9896     if (AssignmentOp.isInvalid())
9897       continue;
9898     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9899                                        /*DiscardedValue=*/true);
9900     if (AssignmentOp.isInvalid())
9901       continue;
9902 
9903     DeclRefExpr *Ref = nullptr;
9904     if (!VD && !CurContext->isDependentContext()) {
9905       if (TopDVar.CKind == OMPC_firstprivate) {
9906         Ref = TopDVar.PrivateCopy;
9907       } else {
9908         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9909         if (!isOpenMPCapturedDecl(D))
9910           ExprCaptures.push_back(Ref->getDecl());
9911       }
9912       if (TopDVar.CKind == OMPC_firstprivate ||
9913           (!isOpenMPCapturedDecl(D) &&
9914            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
9915         ExprResult RefRes = DefaultLvalueConversion(Ref);
9916         if (!RefRes.isUsable())
9917           continue;
9918         ExprResult PostUpdateRes =
9919             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9920                        RefRes.get());
9921         if (!PostUpdateRes.isUsable())
9922           continue;
9923         ExprPostUpdates.push_back(
9924             IgnoredValueConversions(PostUpdateRes.get()).get());
9925       }
9926     }
9927     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9928     Vars.push_back((VD || CurContext->isDependentContext())
9929                        ? RefExpr->IgnoreParens()
9930                        : Ref);
9931     SrcExprs.push_back(PseudoSrcExpr);
9932     DstExprs.push_back(PseudoDstExpr);
9933     AssignmentOps.push_back(AssignmentOp.get());
9934   }
9935 
9936   if (Vars.empty())
9937     return nullptr;
9938 
9939   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9940                                       Vars, SrcExprs, DstExprs, AssignmentOps,
9941                                       buildPreInits(Context, ExprCaptures),
9942                                       buildPostUpdate(*this, ExprPostUpdates));
9943 }
9944 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)9945 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
9946                                          SourceLocation StartLoc,
9947                                          SourceLocation LParenLoc,
9948                                          SourceLocation EndLoc) {
9949   SmallVector<Expr *, 8> Vars;
9950   for (Expr *RefExpr : VarList) {
9951     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9952     SourceLocation ELoc;
9953     SourceRange ERange;
9954     Expr *SimpleRefExpr = RefExpr;
9955     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9956     if (Res.second) {
9957       // It will be analyzed later.
9958       Vars.push_back(RefExpr);
9959     }
9960     ValueDecl *D = Res.first;
9961     if (!D)
9962       continue;
9963 
9964     auto *VD = dyn_cast<VarDecl>(D);
9965     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9966     // in a Construct]
9967     //  Variables with the predetermined data-sharing attributes may not be
9968     //  listed in data-sharing attributes clauses, except for the cases
9969     //  listed below. For these exceptions only, listing a predetermined
9970     //  variable in a data-sharing attribute clause is allowed and overrides
9971     //  the variable's predetermined data-sharing attributes.
9972     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9973     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
9974         DVar.RefExpr) {
9975       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9976                                           << getOpenMPClauseName(OMPC_shared);
9977       reportOriginalDsa(*this, DSAStack, D, DVar);
9978       continue;
9979     }
9980 
9981     DeclRefExpr *Ref = nullptr;
9982     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9983       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9984     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9985     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9986                        ? RefExpr->IgnoreParens()
9987                        : Ref);
9988   }
9989 
9990   if (Vars.empty())
9991     return nullptr;
9992 
9993   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
9994 }
9995 
9996 namespace {
9997 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
9998   DSAStackTy *Stack;
9999 
10000 public:
VisitDeclRefExpr(DeclRefExpr * E)10001   bool VisitDeclRefExpr(DeclRefExpr *E) {
10002     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
10003       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
10004       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10005         return false;
10006       if (DVar.CKind != OMPC_unknown)
10007         return true;
10008       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10009           VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
10010           /*FromParent=*/true);
10011       return DVarPrivate.CKind != OMPC_unknown;
10012     }
10013     return false;
10014   }
VisitStmt(Stmt * S)10015   bool VisitStmt(Stmt *S) {
10016     for (Stmt *Child : S->children()) {
10017       if (Child && Visit(Child))
10018         return true;
10019     }
10020     return false;
10021   }
DSARefChecker(DSAStackTy * S)10022   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10023 };
10024 } // namespace
10025 
10026 namespace {
10027 // Transform MemberExpression for specified FieldDecl of current class to
10028 // DeclRefExpr to specified OMPCapturedExprDecl.
10029 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
10030   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
10031   ValueDecl *Field = nullptr;
10032   DeclRefExpr *CapturedExpr = nullptr;
10033 
10034 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)10035   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
10036       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
10037 
TransformMemberExpr(MemberExpr * E)10038   ExprResult TransformMemberExpr(MemberExpr *E) {
10039     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
10040         E->getMemberDecl() == Field) {
10041       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
10042       return CapturedExpr;
10043     }
10044     return BaseTransform::TransformMemberExpr(E);
10045   }
getCapturedExpr()10046   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
10047 };
10048 } // namespace
10049 
10050 template <typename T, typename U>
filterLookupForUDR(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)10051 static T filterLookupForUDR(SmallVectorImpl<U> &Lookups,
10052                             const llvm::function_ref<T(ValueDecl *)> Gen) {
10053   for (U &Set : Lookups) {
10054     for (auto *D : Set) {
10055       if (T Res = Gen(cast<ValueDecl>(D)))
10056         return Res;
10057     }
10058   }
10059   return T();
10060 }
10061 
10062 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)10063 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
10064                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
10065                          const DeclarationNameInfo &ReductionId, QualType Ty,
10066                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
10067   if (ReductionIdScopeSpec.isInvalid())
10068     return ExprError();
10069   SmallVector<UnresolvedSet<8>, 4> Lookups;
10070   if (S) {
10071     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10072     Lookup.suppressDiagnostics();
10073     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
10074       NamedDecl *D = Lookup.getRepresentativeDecl();
10075       do {
10076         S = S->getParent();
10077       } while (S && !S->isDeclScope(D));
10078       if (S)
10079         S = S->getParent();
10080       Lookups.push_back(UnresolvedSet<8>());
10081       Lookups.back().append(Lookup.begin(), Lookup.end());
10082       Lookup.clear();
10083     }
10084   } else if (auto *ULE =
10085                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10086     Lookups.push_back(UnresolvedSet<8>());
10087     Decl *PrevD = nullptr;
10088     for (NamedDecl *D : ULE->decls()) {
10089       if (D == PrevD)
10090         Lookups.push_back(UnresolvedSet<8>());
10091       else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
10092         Lookups.back().addDecl(DRD);
10093       PrevD = D;
10094     }
10095   }
10096   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
10097       Ty->isInstantiationDependentType() ||
10098       Ty->containsUnexpandedParameterPack() ||
10099       filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) {
10100         return !D->isInvalidDecl() &&
10101                (D->getType()->isDependentType() ||
10102                 D->getType()->isInstantiationDependentType() ||
10103                 D->getType()->containsUnexpandedParameterPack());
10104       })) {
10105     UnresolvedSet<8> ResSet;
10106     for (const UnresolvedSet<8> &Set : Lookups) {
10107       ResSet.append(Set.begin(), Set.end());
10108       // The last item marks the end of all declarations at the specified scope.
10109       ResSet.addDecl(Set[Set.size() - 1]);
10110     }
10111     return UnresolvedLookupExpr::Create(
10112         SemaRef.Context, /*NamingClass=*/nullptr,
10113         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
10114         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
10115   }
10116   if (auto *VD = filterLookupForUDR<ValueDecl *>(
10117           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
10118             if (!D->isInvalidDecl() &&
10119                 SemaRef.Context.hasSameType(D->getType(), Ty))
10120               return D;
10121             return nullptr;
10122           }))
10123     return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10124   if (auto *VD = filterLookupForUDR<ValueDecl *>(
10125           Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
10126             if (!D->isInvalidDecl() &&
10127                 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
10128                 !Ty.isMoreQualifiedThan(D->getType()))
10129               return D;
10130             return nullptr;
10131           })) {
10132     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
10133                        /*DetectVirtual=*/false);
10134     if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10135       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
10136               VD->getType().getUnqualifiedType()))) {
10137         if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
10138                                          /*DiagID=*/0) !=
10139             Sema::AR_inaccessible) {
10140           SemaRef.BuildBasePathArray(Paths, BasePath);
10141           return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10142         }
10143       }
10144     }
10145   }
10146   if (ReductionIdScopeSpec.isSet()) {
10147     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10148     return ExprError();
10149   }
10150   return ExprEmpty();
10151 }
10152 
10153 namespace {
10154 /// Data for the reduction-based clauses.
10155 struct ReductionData {
10156   /// List of original reduction items.
10157   SmallVector<Expr *, 8> Vars;
10158   /// List of private copies of the reduction items.
10159   SmallVector<Expr *, 8> Privates;
10160   /// LHS expressions for the reduction_op expressions.
10161   SmallVector<Expr *, 8> LHSs;
10162   /// RHS expressions for the reduction_op expressions.
10163   SmallVector<Expr *, 8> RHSs;
10164   /// Reduction operation expression.
10165   SmallVector<Expr *, 8> ReductionOps;
10166   /// Taskgroup descriptors for the corresponding reduction items in
10167   /// in_reduction clauses.
10168   SmallVector<Expr *, 8> TaskgroupDescriptors;
10169   /// List of captures for clause.
10170   SmallVector<Decl *, 4> ExprCaptures;
10171   /// List of postupdate expressions.
10172   SmallVector<Expr *, 4> ExprPostUpdates;
10173   ReductionData() = delete;
10174   /// Reserves required memory for the reduction data.
ReductionData__anon0050f7f03311::ReductionData10175   ReductionData(unsigned Size) {
10176     Vars.reserve(Size);
10177     Privates.reserve(Size);
10178     LHSs.reserve(Size);
10179     RHSs.reserve(Size);
10180     ReductionOps.reserve(Size);
10181     TaskgroupDescriptors.reserve(Size);
10182     ExprCaptures.reserve(Size);
10183     ExprPostUpdates.reserve(Size);
10184   }
10185   /// Stores reduction item and reduction operation only (required for dependent
10186   /// reduction item).
push__anon0050f7f03311::ReductionData10187   void push(Expr *Item, Expr *ReductionOp) {
10188     Vars.emplace_back(Item);
10189     Privates.emplace_back(nullptr);
10190     LHSs.emplace_back(nullptr);
10191     RHSs.emplace_back(nullptr);
10192     ReductionOps.emplace_back(ReductionOp);
10193     TaskgroupDescriptors.emplace_back(nullptr);
10194   }
10195   /// Stores reduction data.
push__anon0050f7f03311::ReductionData10196   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
10197             Expr *TaskgroupDescriptor) {
10198     Vars.emplace_back(Item);
10199     Privates.emplace_back(Private);
10200     LHSs.emplace_back(LHS);
10201     RHSs.emplace_back(RHS);
10202     ReductionOps.emplace_back(ReductionOp);
10203     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10204   }
10205 };
10206 } // namespace
10207 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)10208 static bool checkOMPArraySectionConstantForReduction(
10209     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
10210     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
10211   const Expr *Length = OASE->getLength();
10212   if (Length == nullptr) {
10213     // For array sections of the form [1:] or [:], we would need to analyze
10214     // the lower bound...
10215     if (OASE->getColonLoc().isValid())
10216       return false;
10217 
10218     // This is an array subscript which has implicit length 1!
10219     SingleElement = true;
10220     ArraySizes.push_back(llvm::APSInt::get(1));
10221   } else {
10222     llvm::APSInt ConstantLengthValue;
10223     if (!Length->EvaluateAsInt(ConstantLengthValue, Context))
10224       return false;
10225 
10226     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10227     ArraySizes.push_back(ConstantLengthValue);
10228   }
10229 
10230   // Get the base of this array section and walk up from there.
10231   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10232 
10233   // We require length = 1 for all array sections except the right-most to
10234   // guarantee that the memory region is contiguous and has no holes in it.
10235   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10236     Length = TempOASE->getLength();
10237     if (Length == nullptr) {
10238       // For array sections of the form [1:] or [:], we would need to analyze
10239       // the lower bound...
10240       if (OASE->getColonLoc().isValid())
10241         return false;
10242 
10243       // This is an array subscript which has implicit length 1!
10244       ArraySizes.push_back(llvm::APSInt::get(1));
10245     } else {
10246       llvm::APSInt ConstantLengthValue;
10247       if (!Length->EvaluateAsInt(ConstantLengthValue, Context) ||
10248           ConstantLengthValue.getSExtValue() != 1)
10249         return false;
10250 
10251       ArraySizes.push_back(ConstantLengthValue);
10252     }
10253     Base = TempOASE->getBase()->IgnoreParenImpCasts();
10254   }
10255 
10256   // If we have a single element, we don't need to add the implicit lengths.
10257   if (!SingleElement) {
10258     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10259       // Has implicit length 1!
10260       ArraySizes.push_back(llvm::APSInt::get(1));
10261       Base = TempASE->getBase()->IgnoreParenImpCasts();
10262     }
10263   }
10264 
10265   // This array section can be privatized as a single value or as a constant
10266   // sized array.
10267   return true;
10268 }
10269 
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)10270 static bool actOnOMPReductionKindClause(
10271     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
10272     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10273     SourceLocation ColonLoc, SourceLocation EndLoc,
10274     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10275     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
10276   DeclarationName DN = ReductionId.getName();
10277   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
10278   BinaryOperatorKind BOK = BO_Comma;
10279 
10280   ASTContext &Context = S.Context;
10281   // OpenMP [2.14.3.6, reduction clause]
10282   // C
10283   // reduction-identifier is either an identifier or one of the following
10284   // operators: +, -, *,  &, |, ^, && and ||
10285   // C++
10286   // reduction-identifier is either an id-expression or one of the following
10287   // operators: +, -, *, &, |, ^, && and ||
10288   switch (OOK) {
10289   case OO_Plus:
10290   case OO_Minus:
10291     BOK = BO_Add;
10292     break;
10293   case OO_Star:
10294     BOK = BO_Mul;
10295     break;
10296   case OO_Amp:
10297     BOK = BO_And;
10298     break;
10299   case OO_Pipe:
10300     BOK = BO_Or;
10301     break;
10302   case OO_Caret:
10303     BOK = BO_Xor;
10304     break;
10305   case OO_AmpAmp:
10306     BOK = BO_LAnd;
10307     break;
10308   case OO_PipePipe:
10309     BOK = BO_LOr;
10310     break;
10311   case OO_New:
10312   case OO_Delete:
10313   case OO_Array_New:
10314   case OO_Array_Delete:
10315   case OO_Slash:
10316   case OO_Percent:
10317   case OO_Tilde:
10318   case OO_Exclaim:
10319   case OO_Equal:
10320   case OO_Less:
10321   case OO_Greater:
10322   case OO_LessEqual:
10323   case OO_GreaterEqual:
10324   case OO_PlusEqual:
10325   case OO_MinusEqual:
10326   case OO_StarEqual:
10327   case OO_SlashEqual:
10328   case OO_PercentEqual:
10329   case OO_CaretEqual:
10330   case OO_AmpEqual:
10331   case OO_PipeEqual:
10332   case OO_LessLess:
10333   case OO_GreaterGreater:
10334   case OO_LessLessEqual:
10335   case OO_GreaterGreaterEqual:
10336   case OO_EqualEqual:
10337   case OO_ExclaimEqual:
10338   case OO_Spaceship:
10339   case OO_PlusPlus:
10340   case OO_MinusMinus:
10341   case OO_Comma:
10342   case OO_ArrowStar:
10343   case OO_Arrow:
10344   case OO_Call:
10345   case OO_Subscript:
10346   case OO_Conditional:
10347   case OO_Coawait:
10348   case NUM_OVERLOADED_OPERATORS:
10349     llvm_unreachable("Unexpected reduction identifier");
10350   case OO_None:
10351     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
10352       if (II->isStr("max"))
10353         BOK = BO_GT;
10354       else if (II->isStr("min"))
10355         BOK = BO_LT;
10356     }
10357     break;
10358   }
10359   SourceRange ReductionIdRange;
10360   if (ReductionIdScopeSpec.isValid())
10361     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10362   else
10363     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10364   ReductionIdRange.setEnd(ReductionId.getEndLoc());
10365 
10366   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10367   bool FirstIter = true;
10368   for (Expr *RefExpr : VarList) {
10369     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10370     // OpenMP [2.1, C/C++]
10371     //  A list item is a variable or array section, subject to the restrictions
10372     //  specified in Section 2.4 on page 42 and in each of the sections
10373     // describing clauses and directives for which a list appears.
10374     // OpenMP  [2.14.3.3, Restrictions, p.1]
10375     //  A variable that is part of another variable (as an array or
10376     //  structure element) cannot appear in a private clause.
10377     if (!FirstIter && IR != ER)
10378       ++IR;
10379     FirstIter = false;
10380     SourceLocation ELoc;
10381     SourceRange ERange;
10382     Expr *SimpleRefExpr = RefExpr;
10383     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10384                               /*AllowArraySection=*/true);
10385     if (Res.second) {
10386       // Try to find 'declare reduction' corresponding construct before using
10387       // builtin/overloaded operators.
10388       QualType Type = Context.DependentTy;
10389       CXXCastPath BasePath;
10390       ExprResult DeclareReductionRef = buildDeclareReductionRef(
10391           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10392           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10393       Expr *ReductionOp = nullptr;
10394       if (S.CurContext->isDependentContext() &&
10395           (DeclareReductionRef.isUnset() ||
10396            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10397         ReductionOp = DeclareReductionRef.get();
10398       // It will be analyzed later.
10399       RD.push(RefExpr, ReductionOp);
10400     }
10401     ValueDecl *D = Res.first;
10402     if (!D)
10403       continue;
10404 
10405     Expr *TaskgroupDescriptor = nullptr;
10406     QualType Type;
10407     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10408     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10409     if (ASE) {
10410       Type = ASE->getType().getNonReferenceType();
10411     } else if (OASE) {
10412       QualType BaseType =
10413           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
10414       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
10415         Type = ATy->getElementType();
10416       else
10417         Type = BaseType->getPointeeType();
10418       Type = Type.getNonReferenceType();
10419     } else {
10420       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10421     }
10422     auto *VD = dyn_cast<VarDecl>(D);
10423 
10424     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10425     //  A variable that appears in a private clause must not have an incomplete
10426     //  type or a reference type.
10427     if (S.RequireCompleteType(ELoc, D->getType(),
10428                               diag::err_omp_reduction_incomplete_type))
10429       continue;
10430     // OpenMP [2.14.3.6, reduction clause, Restrictions]
10431     // A list item that appears in a reduction clause must not be
10432     // const-qualified.
10433     if (Type.getNonReferenceType().isConstant(Context)) {
10434       S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10435       if (!ASE && !OASE) {
10436         bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10437                                  VarDecl::DeclarationOnly;
10438         S.Diag(D->getLocation(),
10439                IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10440             << D;
10441       }
10442       continue;
10443     }
10444     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
10445     //  If a list-item is a reference type then it must bind to the same object
10446     //  for all threads of the team.
10447     if (!ASE && !OASE && VD) {
10448       VarDecl *VDDef = VD->getDefinition();
10449       if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
10450         DSARefChecker Check(Stack);
10451         if (Check.Visit(VDDef->getInit())) {
10452           S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10453               << getOpenMPClauseName(ClauseKind) << ERange;
10454           S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
10455           continue;
10456         }
10457       }
10458     }
10459 
10460     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10461     // in a Construct]
10462     //  Variables with the predetermined data-sharing attributes may not be
10463     //  listed in data-sharing attributes clauses, except for the cases
10464     //  listed below. For these exceptions only, listing a predetermined
10465     //  variable in a data-sharing attribute clause is allowed and overrides
10466     //  the variable's predetermined data-sharing attributes.
10467     // OpenMP [2.14.3.6, Restrictions, p.3]
10468     //  Any number of reduction clauses can be specified on the directive,
10469     //  but a list item can appear only once in the reduction clauses for that
10470     //  directive.
10471     DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
10472     if (DVar.CKind == OMPC_reduction) {
10473       S.Diag(ELoc, diag::err_omp_once_referenced)
10474           << getOpenMPClauseName(ClauseKind);
10475       if (DVar.RefExpr)
10476         S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10477       continue;
10478     }
10479     if (DVar.CKind != OMPC_unknown) {
10480       S.Diag(ELoc, diag::err_omp_wrong_dsa)
10481           << getOpenMPClauseName(DVar.CKind)
10482           << getOpenMPClauseName(OMPC_reduction);
10483       reportOriginalDsa(S, Stack, D, DVar);
10484       continue;
10485     }
10486 
10487     // OpenMP [2.14.3.6, Restrictions, p.1]
10488     //  A list item that appears in a reduction clause of a worksharing
10489     //  construct must be shared in the parallel regions to which any of the
10490     //  worksharing regions arising from the worksharing construct bind.
10491     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10492     if (isOpenMPWorksharingDirective(CurrDir) &&
10493         !isOpenMPParallelDirective(CurrDir) &&
10494         !isOpenMPTeamsDirective(CurrDir)) {
10495       DVar = Stack->getImplicitDSA(D, true);
10496       if (DVar.CKind != OMPC_shared) {
10497         S.Diag(ELoc, diag::err_omp_required_access)
10498             << getOpenMPClauseName(OMPC_reduction)
10499             << getOpenMPClauseName(OMPC_shared);
10500         reportOriginalDsa(S, Stack, D, DVar);
10501         continue;
10502       }
10503     }
10504 
10505     // Try to find 'declare reduction' corresponding construct before using
10506     // builtin/overloaded operators.
10507     CXXCastPath BasePath;
10508     ExprResult DeclareReductionRef = buildDeclareReductionRef(
10509         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10510         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10511     if (DeclareReductionRef.isInvalid())
10512       continue;
10513     if (S.CurContext->isDependentContext() &&
10514         (DeclareReductionRef.isUnset() ||
10515          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
10516       RD.push(RefExpr, DeclareReductionRef.get());
10517       continue;
10518     }
10519     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
10520       // Not allowed reduction identifier is found.
10521       S.Diag(ReductionId.getLocStart(),
10522              diag::err_omp_unknown_reduction_identifier)
10523           << Type << ReductionIdRange;
10524       continue;
10525     }
10526 
10527     // OpenMP [2.14.3.6, reduction clause, Restrictions]
10528     // The type of a list item that appears in a reduction clause must be valid
10529     // for the reduction-identifier. For a max or min reduction in C, the type
10530     // of the list item must be an allowed arithmetic data type: char, int,
10531     // float, double, or _Bool, possibly modified with long, short, signed, or
10532     // unsigned. For a max or min reduction in C++, the type of the list item
10533     // must be an allowed arithmetic data type: char, wchar_t, int, float,
10534     // double, or bool, possibly modified with long, short, signed, or unsigned.
10535     if (DeclareReductionRef.isUnset()) {
10536       if ((BOK == BO_GT || BOK == BO_LT) &&
10537           !(Type->isScalarType() ||
10538             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10539         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10540             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
10541         if (!ASE && !OASE) {
10542           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10543                                    VarDecl::DeclarationOnly;
10544           S.Diag(D->getLocation(),
10545                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10546               << D;
10547         }
10548         continue;
10549       }
10550       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10551           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
10552         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10553             << getOpenMPClauseName(ClauseKind);
10554         if (!ASE && !OASE) {
10555           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10556                                    VarDecl::DeclarationOnly;
10557           S.Diag(D->getLocation(),
10558                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10559               << D;
10560         }
10561         continue;
10562       }
10563     }
10564 
10565     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10566     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
10567                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
10568     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
10569                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
10570     QualType PrivateTy = Type;
10571 
10572     // Try if we can determine constant lengths for all array sections and avoid
10573     // the VLA.
10574     bool ConstantLengthOASE = false;
10575     if (OASE) {
10576       bool SingleElement;
10577       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
10578       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
10579           Context, OASE, SingleElement, ArraySizes);
10580 
10581       // If we don't have a single element, we must emit a constant array type.
10582       if (ConstantLengthOASE && !SingleElement) {
10583         for (llvm::APSInt &Size : ArraySizes)
10584           PrivateTy = Context.getConstantArrayType(
10585               PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
10586       }
10587     }
10588 
10589     if ((OASE && !ConstantLengthOASE) ||
10590         (!OASE && !ASE &&
10591          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
10592       if (!Context.getTargetInfo().isVLASupported() &&
10593           S.shouldDiagnoseTargetSupportFromOpenMP()) {
10594         S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10595         S.Diag(ELoc, diag::note_vla_unsupported);
10596         continue;
10597       }
10598       // For arrays/array sections only:
10599       // Create pseudo array type for private copy. The size for this array will
10600       // be generated during codegen.
10601       // For array subscripts or single variables Private Ty is the same as Type
10602       // (type of the variable or single array element).
10603       PrivateTy = Context.getVariableArrayType(
10604           Type,
10605           new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
10606           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
10607     } else if (!ASE && !OASE &&
10608                Context.getAsArrayType(D->getType().getNonReferenceType())) {
10609       PrivateTy = D->getType().getNonReferenceType();
10610     }
10611     // Private copy.
10612     VarDecl *PrivateVD =
10613         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
10614                      D->hasAttrs() ? &D->getAttrs() : nullptr,
10615                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10616     // Add initializer for private variable.
10617     Expr *Init = nullptr;
10618     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
10619     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
10620     if (DeclareReductionRef.isUsable()) {
10621       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
10622       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10623       if (DRD->getInitializer()) {
10624         Init = DRDRef;
10625         RHSVD->setInit(DRDRef);
10626         RHSVD->setInitStyle(VarDecl::CallInit);
10627       }
10628     } else {
10629       switch (BOK) {
10630       case BO_Add:
10631       case BO_Xor:
10632       case BO_Or:
10633       case BO_LOr:
10634         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
10635         if (Type->isScalarType() || Type->isAnyComplexType())
10636           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
10637         break;
10638       case BO_Mul:
10639       case BO_LAnd:
10640         if (Type->isScalarType() || Type->isAnyComplexType()) {
10641           // '*' and '&&' reduction ops - initializer is '1'.
10642           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
10643         }
10644         break;
10645       case BO_And: {
10646         // '&' reduction op - initializer is '~0'.
10647         QualType OrigType = Type;
10648         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
10649           Type = ComplexTy->getElementType();
10650         if (Type->isRealFloatingType()) {
10651           llvm::APFloat InitValue =
10652               llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
10653                                              /*isIEEE=*/true);
10654           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10655                                          Type, ELoc);
10656         } else if (Type->isScalarType()) {
10657           uint64_t Size = Context.getTypeSize(Type);
10658           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
10659           llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10660           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10661         }
10662         if (Init && OrigType->isAnyComplexType()) {
10663           // Init = 0xFFFF + 0xFFFFi;
10664           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
10665           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
10666         }
10667         Type = OrigType;
10668         break;
10669       }
10670       case BO_LT:
10671       case BO_GT: {
10672         // 'min' reduction op - initializer is 'Largest representable number in
10673         // the reduction list item type'.
10674         // 'max' reduction op - initializer is 'Least representable number in
10675         // the reduction list item type'.
10676         if (Type->isIntegerType() || Type->isPointerType()) {
10677           bool IsSigned = Type->hasSignedIntegerRepresentation();
10678           uint64_t Size = Context.getTypeSize(Type);
10679           QualType IntTy =
10680               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
10681           llvm::APInt InitValue =
10682               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10683                                         : llvm::APInt::getMinValue(Size)
10684                              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10685                                         : llvm::APInt::getMaxValue(Size);
10686           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10687           if (Type->isPointerType()) {
10688             // Cast to pointer type.
10689             ExprResult CastExpr = S.BuildCStyleCastExpr(
10690                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
10691             if (CastExpr.isInvalid())
10692               continue;
10693             Init = CastExpr.get();
10694           }
10695         } else if (Type->isRealFloatingType()) {
10696           llvm::APFloat InitValue = llvm::APFloat::getLargest(
10697               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
10698           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10699                                          Type, ELoc);
10700         }
10701         break;
10702       }
10703       case BO_PtrMemD:
10704       case BO_PtrMemI:
10705       case BO_MulAssign:
10706       case BO_Div:
10707       case BO_Rem:
10708       case BO_Sub:
10709       case BO_Shl:
10710       case BO_Shr:
10711       case BO_LE:
10712       case BO_GE:
10713       case BO_EQ:
10714       case BO_NE:
10715       case BO_Cmp:
10716       case BO_AndAssign:
10717       case BO_XorAssign:
10718       case BO_OrAssign:
10719       case BO_Assign:
10720       case BO_AddAssign:
10721       case BO_SubAssign:
10722       case BO_DivAssign:
10723       case BO_RemAssign:
10724       case BO_ShlAssign:
10725       case BO_ShrAssign:
10726       case BO_Comma:
10727         llvm_unreachable("Unexpected reduction operation");
10728       }
10729     }
10730     if (Init && DeclareReductionRef.isUnset())
10731       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
10732     else if (!Init)
10733       S.ActOnUninitializedDecl(RHSVD);
10734     if (RHSVD->isInvalidDecl())
10735       continue;
10736     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
10737       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10738           << Type << ReductionIdRange;
10739       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10740                                VarDecl::DeclarationOnly;
10741       S.Diag(D->getLocation(),
10742              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10743           << D;
10744       continue;
10745     }
10746     // Store initializer for single element in private copy. Will be used during
10747     // codegen.
10748     PrivateVD->setInit(RHSVD->getInit());
10749     PrivateVD->setInitStyle(RHSVD->getInitStyle());
10750     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
10751     ExprResult ReductionOp;
10752     if (DeclareReductionRef.isUsable()) {
10753       QualType RedTy = DeclareReductionRef.get()->getType();
10754       QualType PtrRedTy = Context.getPointerType(RedTy);
10755       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
10756       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
10757       if (!BasePath.empty()) {
10758         LHS = S.DefaultLvalueConversion(LHS.get());
10759         RHS = S.DefaultLvalueConversion(RHS.get());
10760         LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10761                                        CK_UncheckedDerivedToBase, LHS.get(),
10762                                        &BasePath, LHS.get()->getValueKind());
10763         RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10764                                        CK_UncheckedDerivedToBase, RHS.get(),
10765                                        &BasePath, RHS.get()->getValueKind());
10766       }
10767       FunctionProtoType::ExtProtoInfo EPI;
10768       QualType Params[] = {PtrRedTy, PtrRedTy};
10769       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
10770       auto *OVE = new (Context) OpaqueValueExpr(
10771           ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
10772           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
10773       Expr *Args[] = {LHS.get(), RHS.get()};
10774       ReductionOp = new (Context)
10775           CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
10776     } else {
10777       ReductionOp = S.BuildBinOp(
10778           Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10779       if (ReductionOp.isUsable()) {
10780         if (BOK != BO_LT && BOK != BO_GT) {
10781           ReductionOp =
10782               S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10783                            BO_Assign, LHSDRE, ReductionOp.get());
10784         } else {
10785           auto *ConditionalOp = new (Context)
10786               ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
10787                                   Type, VK_LValue, OK_Ordinary);
10788           ReductionOp =
10789               S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10790                            BO_Assign, LHSDRE, ConditionalOp);
10791         }
10792         if (ReductionOp.isUsable())
10793           ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
10794       }
10795       if (!ReductionOp.isUsable())
10796         continue;
10797     }
10798 
10799     // OpenMP [2.15.4.6, Restrictions, p.2]
10800     // A list item that appears in an in_reduction clause of a task construct
10801     // must appear in a task_reduction clause of a construct associated with a
10802     // taskgroup region that includes the participating task in its taskgroup
10803     // set. The construct associated with the innermost region that meets this
10804     // condition must specify the same reduction-identifier as the in_reduction
10805     // clause.
10806     if (ClauseKind == OMPC_in_reduction) {
10807       SourceRange ParentSR;
10808       BinaryOperatorKind ParentBOK;
10809       const Expr *ParentReductionOp;
10810       Expr *ParentBOKTD, *ParentReductionOpTD;
10811       DSAStackTy::DSAVarData ParentBOKDSA =
10812           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10813                                                   ParentBOKTD);
10814       DSAStackTy::DSAVarData ParentReductionOpDSA =
10815           Stack->getTopMostTaskgroupReductionData(
10816               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10817       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
10818       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
10819       if (!IsParentBOK && !IsParentReductionOp) {
10820         S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10821         continue;
10822       }
10823       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
10824           (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
10825           IsParentReductionOp) {
10826         bool EmitError = true;
10827         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
10828           llvm::FoldingSetNodeID RedId, ParentRedId;
10829           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
10830           DeclareReductionRef.get()->Profile(RedId, Context,
10831                                              /*Canonical=*/true);
10832           EmitError = RedId != ParentRedId;
10833         }
10834         if (EmitError) {
10835           S.Diag(ReductionId.getLocStart(),
10836                  diag::err_omp_reduction_identifier_mismatch)
10837               << ReductionIdRange << RefExpr->getSourceRange();
10838           S.Diag(ParentSR.getBegin(),
10839                  diag::note_omp_previous_reduction_identifier)
10840               << ParentSR
10841               << (IsParentBOK ? ParentBOKDSA.RefExpr
10842                               : ParentReductionOpDSA.RefExpr)
10843                      ->getSourceRange();
10844           continue;
10845         }
10846       }
10847       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10848       assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
10849     }
10850 
10851     DeclRefExpr *Ref = nullptr;
10852     Expr *VarsExpr = RefExpr->IgnoreParens();
10853     if (!VD && !S.CurContext->isDependentContext()) {
10854       if (ASE || OASE) {
10855         TransformExprToCaptures RebuildToCapture(S, D);
10856         VarsExpr =
10857             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
10858         Ref = RebuildToCapture.getCapturedExpr();
10859       } else {
10860         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
10861       }
10862       if (!S.isOpenMPCapturedDecl(D)) {
10863         RD.ExprCaptures.emplace_back(Ref->getDecl());
10864         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10865           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
10866           if (!RefRes.isUsable())
10867             continue;
10868           ExprResult PostUpdateRes =
10869               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10870                            RefRes.get());
10871           if (!PostUpdateRes.isUsable())
10872             continue;
10873           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
10874               Stack->getCurrentDirective() == OMPD_taskgroup) {
10875             S.Diag(RefExpr->getExprLoc(),
10876                    diag::err_omp_reduction_non_addressable_expression)
10877                 << RefExpr->getSourceRange();
10878             continue;
10879           }
10880           RD.ExprPostUpdates.emplace_back(
10881               S.IgnoredValueConversions(PostUpdateRes.get()).get());
10882         }
10883       }
10884     }
10885     // All reduction items are still marked as reduction (to do not increase
10886     // code base size).
10887     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10888     if (CurrDir == OMPD_taskgroup) {
10889       if (DeclareReductionRef.isUsable())
10890         Stack->addTaskgroupReductionData(D, ReductionIdRange,
10891                                          DeclareReductionRef.get());
10892       else
10893         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10894     }
10895     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
10896             TaskgroupDescriptor);
10897   }
10898   return RD.Vars.empty();
10899 }
10900 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)10901 OMPClause *Sema::ActOnOpenMPReductionClause(
10902     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10903     SourceLocation ColonLoc, SourceLocation EndLoc,
10904     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10905     ArrayRef<Expr *> UnresolvedReductions) {
10906   ReductionData RD(VarList.size());
10907   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
10908                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
10909                                   ReductionIdScopeSpec, ReductionId,
10910                                   UnresolvedReductions, RD))
10911     return nullptr;
10912 
10913   return OMPReductionClause::Create(
10914       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10915       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10916       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10917       buildPreInits(Context, RD.ExprCaptures),
10918       buildPostUpdate(*this, RD.ExprPostUpdates));
10919 }
10920 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)10921 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
10922     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10923     SourceLocation ColonLoc, SourceLocation EndLoc,
10924     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10925     ArrayRef<Expr *> UnresolvedReductions) {
10926   ReductionData RD(VarList.size());
10927   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
10928                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
10929                                   ReductionIdScopeSpec, ReductionId,
10930                                   UnresolvedReductions, RD))
10931     return nullptr;
10932 
10933   return OMPTaskReductionClause::Create(
10934       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10935       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10936       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10937       buildPreInits(Context, RD.ExprCaptures),
10938       buildPostUpdate(*this, RD.ExprPostUpdates));
10939 }
10940 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)10941 OMPClause *Sema::ActOnOpenMPInReductionClause(
10942     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10943     SourceLocation ColonLoc, SourceLocation EndLoc,
10944     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10945     ArrayRef<Expr *> UnresolvedReductions) {
10946   ReductionData RD(VarList.size());
10947   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
10948                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
10949                                   ReductionIdScopeSpec, ReductionId,
10950                                   UnresolvedReductions, RD))
10951     return nullptr;
10952 
10953   return OMPInReductionClause::Create(
10954       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10955       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10956       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10957       buildPreInits(Context, RD.ExprCaptures),
10958       buildPostUpdate(*this, RD.ExprPostUpdates));
10959 }
10960 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)10961 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
10962                                      SourceLocation LinLoc) {
10963   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10964       LinKind == OMPC_LINEAR_unknown) {
10965     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10966     return true;
10967   }
10968   return false;
10969 }
10970 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type)10971 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
10972                                  OpenMPLinearClauseKind LinKind,
10973                                  QualType Type) {
10974   const auto *VD = dyn_cast_or_null<VarDecl>(D);
10975   // A variable must not have an incomplete type or a reference type.
10976   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10977     return true;
10978   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10979       !Type->isReferenceType()) {
10980     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10981         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
10982     return true;
10983   }
10984   Type = Type.getNonReferenceType();
10985 
10986   // A list item must not be const-qualified.
10987   if (Type.isConstant(Context)) {
10988     Diag(ELoc, diag::err_omp_const_variable)
10989         << getOpenMPClauseName(OMPC_linear);
10990     if (D) {
10991       bool IsDecl =
10992           !VD ||
10993           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10994       Diag(D->getLocation(),
10995            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10996           << D;
10997     }
10998     return true;
10999   }
11000 
11001   // A list item must be of integral or pointer type.
11002   Type = Type.getUnqualifiedType().getCanonicalType();
11003   const auto *Ty = Type.getTypePtrOrNull();
11004   if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11005               !Ty->isPointerType())) {
11006     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11007     if (D) {
11008       bool IsDecl =
11009           !VD ||
11010           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11011       Diag(D->getLocation(),
11012            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11013           << D;
11014     }
11015     return true;
11016   }
11017   return false;
11018 }
11019 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)11020 OMPClause *Sema::ActOnOpenMPLinearClause(
11021     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
11022     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
11023     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
11024   SmallVector<Expr *, 8> Vars;
11025   SmallVector<Expr *, 8> Privates;
11026   SmallVector<Expr *, 8> Inits;
11027   SmallVector<Decl *, 4> ExprCaptures;
11028   SmallVector<Expr *, 4> ExprPostUpdates;
11029   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11030     LinKind = OMPC_LINEAR_val;
11031   for (Expr *RefExpr : VarList) {
11032     assert(RefExpr && "NULL expr in OpenMP linear clause.");
11033     SourceLocation ELoc;
11034     SourceRange ERange;
11035     Expr *SimpleRefExpr = RefExpr;
11036     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11037                               /*AllowArraySection=*/false);
11038     if (Res.second) {
11039       // It will be analyzed later.
11040       Vars.push_back(RefExpr);
11041       Privates.push_back(nullptr);
11042       Inits.push_back(nullptr);
11043     }
11044     ValueDecl *D = Res.first;
11045     if (!D)
11046       continue;
11047 
11048     QualType Type = D->getType();
11049     auto *VD = dyn_cast<VarDecl>(D);
11050 
11051     // OpenMP [2.14.3.7, linear clause]
11052     //  A list-item cannot appear in more than one linear clause.
11053     //  A list-item that appears in a linear clause cannot appear in any
11054     //  other data-sharing attribute clause.
11055     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
11056     if (DVar.RefExpr) {
11057       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
11058                                           << getOpenMPClauseName(OMPC_linear);
11059       reportOriginalDsa(*this, DSAStack, D, DVar);
11060       continue;
11061     }
11062 
11063     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11064       continue;
11065     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
11066 
11067     // Build private copy of original var.
11068     VarDecl *Private =
11069         buildVarDecl(*this, ELoc, Type, D->getName(),
11070                      D->hasAttrs() ? &D->getAttrs() : nullptr,
11071                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11072     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
11073     // Build var to save initial value.
11074     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
11075     Expr *InitExpr;
11076     DeclRefExpr *Ref = nullptr;
11077     if (!VD && !CurContext->isDependentContext()) {
11078       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
11079       if (!isOpenMPCapturedDecl(D)) {
11080         ExprCaptures.push_back(Ref->getDecl());
11081         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11082           ExprResult RefRes = DefaultLvalueConversion(Ref);
11083           if (!RefRes.isUsable())
11084             continue;
11085           ExprResult PostUpdateRes =
11086               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11087                          SimpleRefExpr, RefRes.get());
11088           if (!PostUpdateRes.isUsable())
11089             continue;
11090           ExprPostUpdates.push_back(
11091               IgnoredValueConversions(PostUpdateRes.get()).get());
11092         }
11093       }
11094     }
11095     if (LinKind == OMPC_LINEAR_uval)
11096       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11097     else
11098       InitExpr = VD ? SimpleRefExpr : Ref;
11099     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
11100                          /*DirectInit=*/false);
11101     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
11102 
11103     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11104     Vars.push_back((VD || CurContext->isDependentContext())
11105                        ? RefExpr->IgnoreParens()
11106                        : Ref);
11107     Privates.push_back(PrivateRef);
11108     Inits.push_back(InitRef);
11109   }
11110 
11111   if (Vars.empty())
11112     return nullptr;
11113 
11114   Expr *StepExpr = Step;
11115   Expr *CalcStepExpr = nullptr;
11116   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
11117       !Step->isInstantiationDependent() &&
11118       !Step->containsUnexpandedParameterPack()) {
11119     SourceLocation StepLoc = Step->getLocStart();
11120     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11121     if (Val.isInvalid())
11122       return nullptr;
11123     StepExpr = Val.get();
11124 
11125     // Build var to save the step value.
11126     VarDecl *SaveVar =
11127         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
11128     ExprResult SaveRef =
11129         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
11130     ExprResult CalcStep =
11131         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11132     CalcStep = ActOnFinishFullExpr(CalcStep.get());
11133 
11134     // Warn about zero linear step (it would be probably better specified as
11135     // making corresponding variables 'const').
11136     llvm::APSInt Result;
11137     bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
11138     if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11139       Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11140                                                      << (Vars.size() > 1);
11141     if (!IsConstant && CalcStep.isUsable()) {
11142       // Calculate the step beforehand instead of doing this on each iteration.
11143       // (This is not used if the number of iterations may be kfold-ed).
11144       CalcStepExpr = CalcStep.get();
11145     }
11146   }
11147 
11148   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
11149                                  ColonLoc, EndLoc, Vars, Privates, Inits,
11150                                  StepExpr, CalcStepExpr,
11151                                  buildPreInits(Context, ExprCaptures),
11152                                  buildPostUpdate(*this, ExprPostUpdates));
11153 }
11154 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)11155 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
11156                                      Expr *NumIterations, Sema &SemaRef,
11157                                      Scope *S, DSAStackTy *Stack) {
11158   // Walk the vars and build update/final expressions for the CodeGen.
11159   SmallVector<Expr *, 8> Updates;
11160   SmallVector<Expr *, 8> Finals;
11161   Expr *Step = Clause.getStep();
11162   Expr *CalcStep = Clause.getCalcStep();
11163   // OpenMP [2.14.3.7, linear clause]
11164   // If linear-step is not specified it is assumed to be 1.
11165   if (!Step)
11166     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
11167   else if (CalcStep)
11168     Step = cast<BinaryOperator>(CalcStep)->getLHS();
11169   bool HasErrors = false;
11170   auto CurInit = Clause.inits().begin();
11171   auto CurPrivate = Clause.privates().begin();
11172   OpenMPLinearClauseKind LinKind = Clause.getModifier();
11173   for (Expr *RefExpr : Clause.varlists()) {
11174     SourceLocation ELoc;
11175     SourceRange ERange;
11176     Expr *SimpleRefExpr = RefExpr;
11177     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
11178                               /*AllowArraySection=*/false);
11179     ValueDecl *D = Res.first;
11180     if (Res.second || !D) {
11181       Updates.push_back(nullptr);
11182       Finals.push_back(nullptr);
11183       HasErrors = true;
11184       continue;
11185     }
11186     auto &&Info = Stack->isLoopControlVariable(D);
11187     // OpenMP [2.15.11, distribute simd Construct]
11188     // A list item may not appear in a linear clause, unless it is the loop
11189     // iteration variable.
11190     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
11191         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
11192       SemaRef.Diag(ELoc,
11193                    diag::err_omp_linear_distribute_var_non_loop_iteration);
11194       Updates.push_back(nullptr);
11195       Finals.push_back(nullptr);
11196       HasErrors = true;
11197       continue;
11198     }
11199     Expr *InitExpr = *CurInit;
11200 
11201     // Build privatized reference to the current linear var.
11202     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11203     Expr *CapturedRef;
11204     if (LinKind == OMPC_LINEAR_uval)
11205       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11206     else
11207       CapturedRef =
11208           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
11209                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11210                            /*RefersToCapture=*/true);
11211 
11212     // Build update: Var = InitExpr + IV * Step
11213     ExprResult Update;
11214     if (!Info.first)
11215       Update =
11216           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
11217                              InitExpr, IV, Step, /* Subtract */ false);
11218     else
11219       Update = *CurPrivate;
11220     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
11221                                          /*DiscardedValue=*/true);
11222 
11223     // Build final: Var = InitExpr + NumIterations * Step
11224     ExprResult Final;
11225     if (!Info.first)
11226       Final =
11227           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
11228                              InitExpr, NumIterations, Step, /*Subtract=*/false);
11229     else
11230       Final = *CurPrivate;
11231     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
11232                                         /*DiscardedValue=*/true);
11233 
11234     if (!Update.isUsable() || !Final.isUsable()) {
11235       Updates.push_back(nullptr);
11236       Finals.push_back(nullptr);
11237       HasErrors = true;
11238     } else {
11239       Updates.push_back(Update.get());
11240       Finals.push_back(Final.get());
11241     }
11242     ++CurInit;
11243     ++CurPrivate;
11244   }
11245   Clause.setUpdates(Updates);
11246   Clause.setFinals(Finals);
11247   return HasErrors;
11248 }
11249 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)11250 OMPClause *Sema::ActOnOpenMPAlignedClause(
11251     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
11252     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
11253   SmallVector<Expr *, 8> Vars;
11254   for (Expr *RefExpr : VarList) {
11255     assert(RefExpr && "NULL expr in OpenMP linear clause.");
11256     SourceLocation ELoc;
11257     SourceRange ERange;
11258     Expr *SimpleRefExpr = RefExpr;
11259     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11260                               /*AllowArraySection=*/false);
11261     if (Res.second) {
11262       // It will be analyzed later.
11263       Vars.push_back(RefExpr);
11264     }
11265     ValueDecl *D = Res.first;
11266     if (!D)
11267       continue;
11268 
11269     QualType QType = D->getType();
11270     auto *VD = dyn_cast<VarDecl>(D);
11271 
11272     // OpenMP  [2.8.1, simd construct, Restrictions]
11273     // The type of list items appearing in the aligned clause must be
11274     // array, pointer, reference to array, or reference to pointer.
11275     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
11276     const Type *Ty = QType.getTypePtrOrNull();
11277     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
11278       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11279           << QType << getLangOpts().CPlusPlus << ERange;
11280       bool IsDecl =
11281           !VD ||
11282           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11283       Diag(D->getLocation(),
11284            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11285           << D;
11286       continue;
11287     }
11288 
11289     // OpenMP  [2.8.1, simd construct, Restrictions]
11290     // A list-item cannot appear in more than one aligned clause.
11291     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11292       Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11293       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11294           << getOpenMPClauseName(OMPC_aligned);
11295       continue;
11296     }
11297 
11298     DeclRefExpr *Ref = nullptr;
11299     if (!VD && isOpenMPCapturedDecl(D))
11300       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
11301     Vars.push_back(DefaultFunctionArrayConversion(
11302                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11303                        .get());
11304   }
11305 
11306   // OpenMP [2.8.1, simd construct, Description]
11307   // The parameter of the aligned clause, alignment, must be a constant
11308   // positive integer expression.
11309   // If no optional parameter is specified, implementation-defined default
11310   // alignments for SIMD instructions on the target platforms are assumed.
11311   if (Alignment != nullptr) {
11312     ExprResult AlignResult =
11313         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11314     if (AlignResult.isInvalid())
11315       return nullptr;
11316     Alignment = AlignResult.get();
11317   }
11318   if (Vars.empty())
11319     return nullptr;
11320 
11321   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
11322                                   EndLoc, Vars, Alignment);
11323 }
11324 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11325 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
11326                                          SourceLocation StartLoc,
11327                                          SourceLocation LParenLoc,
11328                                          SourceLocation EndLoc) {
11329   SmallVector<Expr *, 8> Vars;
11330   SmallVector<Expr *, 8> SrcExprs;
11331   SmallVector<Expr *, 8> DstExprs;
11332   SmallVector<Expr *, 8> AssignmentOps;
11333   for (Expr *RefExpr : VarList) {
11334     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
11335     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11336       // It will be analyzed later.
11337       Vars.push_back(RefExpr);
11338       SrcExprs.push_back(nullptr);
11339       DstExprs.push_back(nullptr);
11340       AssignmentOps.push_back(nullptr);
11341       continue;
11342     }
11343 
11344     SourceLocation ELoc = RefExpr->getExprLoc();
11345     // OpenMP [2.1, C/C++]
11346     //  A list item is a variable name.
11347     // OpenMP  [2.14.4.1, Restrictions, p.1]
11348     //  A list item that appears in a copyin clause must be threadprivate.
11349     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
11350     if (!DE || !isa<VarDecl>(DE->getDecl())) {
11351       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11352           << 0 << RefExpr->getSourceRange();
11353       continue;
11354     }
11355 
11356     Decl *D = DE->getDecl();
11357     auto *VD = cast<VarDecl>(D);
11358 
11359     QualType Type = VD->getType();
11360     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11361       // It will be analyzed later.
11362       Vars.push_back(DE);
11363       SrcExprs.push_back(nullptr);
11364       DstExprs.push_back(nullptr);
11365       AssignmentOps.push_back(nullptr);
11366       continue;
11367     }
11368 
11369     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11370     //  A list item that appears in a copyin clause must be threadprivate.
11371     if (!DSAStack->isThreadPrivate(VD)) {
11372       Diag(ELoc, diag::err_omp_required_access)
11373           << getOpenMPClauseName(OMPC_copyin)
11374           << getOpenMPDirectiveName(OMPD_threadprivate);
11375       continue;
11376     }
11377 
11378     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11379     //  A variable of class type (or array thereof) that appears in a
11380     //  copyin clause requires an accessible, unambiguous copy assignment
11381     //  operator for the class type.
11382     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11383     VarDecl *SrcVD =
11384         buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
11385                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11386     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
11387         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11388     VarDecl *DstVD =
11389         buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
11390                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11391     DeclRefExpr *PseudoDstExpr =
11392         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11393     // For arrays generate assignment operation for single element and replace
11394     // it by the original array element in CodeGen.
11395     ExprResult AssignmentOp =
11396         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11397                    PseudoSrcExpr);
11398     if (AssignmentOp.isInvalid())
11399       continue;
11400     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11401                                        /*DiscardedValue=*/true);
11402     if (AssignmentOp.isInvalid())
11403       continue;
11404 
11405     DSAStack->addDSA(VD, DE, OMPC_copyin);
11406     Vars.push_back(DE);
11407     SrcExprs.push_back(PseudoSrcExpr);
11408     DstExprs.push_back(PseudoDstExpr);
11409     AssignmentOps.push_back(AssignmentOp.get());
11410   }
11411 
11412   if (Vars.empty())
11413     return nullptr;
11414 
11415   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11416                                  SrcExprs, DstExprs, AssignmentOps);
11417 }
11418 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11419 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
11420                                               SourceLocation StartLoc,
11421                                               SourceLocation LParenLoc,
11422                                               SourceLocation EndLoc) {
11423   SmallVector<Expr *, 8> Vars;
11424   SmallVector<Expr *, 8> SrcExprs;
11425   SmallVector<Expr *, 8> DstExprs;
11426   SmallVector<Expr *, 8> AssignmentOps;
11427   for (Expr *RefExpr : VarList) {
11428     assert(RefExpr && "NULL expr in OpenMP linear clause.");
11429     SourceLocation ELoc;
11430     SourceRange ERange;
11431     Expr *SimpleRefExpr = RefExpr;
11432     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11433                               /*AllowArraySection=*/false);
11434     if (Res.second) {
11435       // It will be analyzed later.
11436       Vars.push_back(RefExpr);
11437       SrcExprs.push_back(nullptr);
11438       DstExprs.push_back(nullptr);
11439       AssignmentOps.push_back(nullptr);
11440     }
11441     ValueDecl *D = Res.first;
11442     if (!D)
11443       continue;
11444 
11445     QualType Type = D->getType();
11446     auto *VD = dyn_cast<VarDecl>(D);
11447 
11448     // OpenMP [2.14.4.2, Restrictions, p.2]
11449     //  A list item that appears in a copyprivate clause may not appear in a
11450     //  private or firstprivate clause on the single construct.
11451     if (!VD || !DSAStack->isThreadPrivate(VD)) {
11452       DSAStackTy::DSAVarData DVar =
11453           DSAStack->getTopDSA(D, /*FromParent=*/false);
11454       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11455           DVar.RefExpr) {
11456         Diag(ELoc, diag::err_omp_wrong_dsa)
11457             << getOpenMPClauseName(DVar.CKind)
11458             << getOpenMPClauseName(OMPC_copyprivate);
11459         reportOriginalDsa(*this, DSAStack, D, DVar);
11460         continue;
11461       }
11462 
11463       // OpenMP [2.11.4.2, Restrictions, p.1]
11464       //  All list items that appear in a copyprivate clause must be either
11465       //  threadprivate or private in the enclosing context.
11466       if (DVar.CKind == OMPC_unknown) {
11467         DVar = DSAStack->getImplicitDSA(D, false);
11468         if (DVar.CKind == OMPC_shared) {
11469           Diag(ELoc, diag::err_omp_required_access)
11470               << getOpenMPClauseName(OMPC_copyprivate)
11471               << "threadprivate or private in the enclosing context";
11472           reportOriginalDsa(*this, DSAStack, D, DVar);
11473           continue;
11474         }
11475       }
11476     }
11477 
11478     // Variably modified types are not supported.
11479     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
11480       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11481           << getOpenMPClauseName(OMPC_copyprivate) << Type
11482           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
11483       bool IsDecl =
11484           !VD ||
11485           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11486       Diag(D->getLocation(),
11487            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11488           << D;
11489       continue;
11490     }
11491 
11492     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11493     //  A variable of class type (or array thereof) that appears in a
11494     //  copyin clause requires an accessible, unambiguous copy assignment
11495     //  operator for the class type.
11496     Type = Context.getBaseElementType(Type.getNonReferenceType())
11497                .getUnqualifiedType();
11498     VarDecl *SrcVD =
11499         buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
11500                      D->hasAttrs() ? &D->getAttrs() : nullptr);
11501     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
11502     VarDecl *DstVD =
11503         buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
11504                      D->hasAttrs() ? &D->getAttrs() : nullptr);
11505     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
11506     ExprResult AssignmentOp = BuildBinOp(
11507         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
11508     if (AssignmentOp.isInvalid())
11509       continue;
11510     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11511                                        /*DiscardedValue=*/true);
11512     if (AssignmentOp.isInvalid())
11513       continue;
11514 
11515     // No need to mark vars as copyprivate, they are already threadprivate or
11516     // implicitly private.
11517     assert(VD || isOpenMPCapturedDecl(D));
11518     Vars.push_back(
11519         VD ? RefExpr->IgnoreParens()
11520            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
11521     SrcExprs.push_back(PseudoSrcExpr);
11522     DstExprs.push_back(PseudoDstExpr);
11523     AssignmentOps.push_back(AssignmentOp.get());
11524   }
11525 
11526   if (Vars.empty())
11527     return nullptr;
11528 
11529   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11530                                       Vars, SrcExprs, DstExprs, AssignmentOps);
11531 }
11532 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11533 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
11534                                         SourceLocation StartLoc,
11535                                         SourceLocation LParenLoc,
11536                                         SourceLocation EndLoc) {
11537   if (VarList.empty())
11538     return nullptr;
11539 
11540   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
11541 }
11542 
11543 OMPClause *
ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11544 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
11545                               SourceLocation DepLoc, SourceLocation ColonLoc,
11546                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11547                               SourceLocation LParenLoc, SourceLocation EndLoc) {
11548   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
11549       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11550     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11551         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
11552     return nullptr;
11553   }
11554   if (DSAStack->getCurrentDirective() != OMPD_ordered &&
11555       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
11556        DepKind == OMPC_DEPEND_sink)) {
11557     unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11558     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11559         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
11560                                    /*Last=*/OMPC_DEPEND_unknown, Except)
11561         << getOpenMPClauseName(OMPC_depend);
11562     return nullptr;
11563   }
11564   SmallVector<Expr *, 8> Vars;
11565   DSAStackTy::OperatorOffsetTy OpsOffs;
11566   llvm::APSInt DepCounter(/*BitWidth=*/32);
11567   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
11568   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
11569     if (const Expr *OrderedCountExpr =
11570             DSAStack->getParentOrderedRegionParam().first) {
11571       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11572       TotalDepCount.setIsUnsigned(/*Val=*/true);
11573     }
11574   }
11575   for (Expr *RefExpr : VarList) {
11576     assert(RefExpr && "NULL expr in OpenMP shared clause.");
11577     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11578       // It will be analyzed later.
11579       Vars.push_back(RefExpr);
11580       continue;
11581     }
11582 
11583     SourceLocation ELoc = RefExpr->getExprLoc();
11584     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
11585     if (DepKind == OMPC_DEPEND_sink) {
11586       if (DSAStack->getParentOrderedRegionParam().first &&
11587           DepCounter >= TotalDepCount) {
11588         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11589         continue;
11590       }
11591       ++DepCounter;
11592       // OpenMP  [2.13.9, Summary]
11593       // depend(dependence-type : vec), where dependence-type is:
11594       // 'sink' and where vec is the iteration vector, which has the form:
11595       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
11596       // where n is the value specified by the ordered clause in the loop
11597       // directive, xi denotes the loop iteration variable of the i-th nested
11598       // loop associated with the loop directive, and di is a constant
11599       // non-negative integer.
11600       if (CurContext->isDependentContext()) {
11601         // It will be analyzed later.
11602         Vars.push_back(RefExpr);
11603         continue;
11604       }
11605       SimpleExpr = SimpleExpr->IgnoreImplicit();
11606       OverloadedOperatorKind OOK = OO_None;
11607       SourceLocation OOLoc;
11608       Expr *LHS = SimpleExpr;
11609       Expr *RHS = nullptr;
11610       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11611         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
11612         OOLoc = BO->getOperatorLoc();
11613         LHS = BO->getLHS()->IgnoreParenImpCasts();
11614         RHS = BO->getRHS()->IgnoreParenImpCasts();
11615       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11616         OOK = OCE->getOperator();
11617         OOLoc = OCE->getOperatorLoc();
11618         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11619         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
11620       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11621         OOK = MCE->getMethodDecl()
11622                   ->getNameInfo()
11623                   .getName()
11624                   .getCXXOverloadedOperator();
11625         OOLoc = MCE->getCallee()->getExprLoc();
11626         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
11627         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11628       }
11629       SourceLocation ELoc;
11630       SourceRange ERange;
11631       auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
11632                                 /*AllowArraySection=*/false);
11633       if (Res.second) {
11634         // It will be analyzed later.
11635         Vars.push_back(RefExpr);
11636       }
11637       ValueDecl *D = Res.first;
11638       if (!D)
11639         continue;
11640 
11641       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
11642         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11643         continue;
11644       }
11645       if (RHS) {
11646         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11647             RHS, OMPC_depend, /*StrictlyPositive=*/false);
11648         if (RHSRes.isInvalid())
11649           continue;
11650       }
11651       if (!CurContext->isDependentContext() &&
11652           DSAStack->getParentOrderedRegionParam().first &&
11653           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
11654         const ValueDecl *VD =
11655             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
11656         if (VD)
11657           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11658               << 1 << VD;
11659         else
11660           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11661         continue;
11662       }
11663       OpsOffs.emplace_back(RHS, OOK);
11664     } else {
11665       auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
11666       if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11667           (ASE &&
11668            !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
11669            !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11670         Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11671             << RefExpr->getSourceRange();
11672         continue;
11673       }
11674       bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11675       getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
11676       ExprResult Res =
11677           CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
11678       getDiagnostics().setSuppressAllDiagnostics(Suppress);
11679       if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11680         Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11681             << RefExpr->getSourceRange();
11682         continue;
11683       }
11684     }
11685     Vars.push_back(RefExpr->IgnoreParenImpCasts());
11686   }
11687 
11688   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11689       TotalDepCount > VarList.size() &&
11690       DSAStack->getParentOrderedRegionParam().first &&
11691       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11692     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
11693         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11694   }
11695   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11696       Vars.empty())
11697     return nullptr;
11698 
11699   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11700                                     DepKind, DepLoc, ColonLoc, Vars,
11701                                     TotalDepCount.getZExtValue());
11702   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
11703       DSAStack->isParentOrderedRegion())
11704     DSAStack->addDoacrossDependClause(C, OpsOffs);
11705   return C;
11706 }
11707 
ActOnOpenMPDeviceClause(Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)11708 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
11709                                          SourceLocation LParenLoc,
11710                                          SourceLocation EndLoc) {
11711   Expr *ValExpr = Device;
11712   Stmt *HelperValStmt = nullptr;
11713 
11714   // OpenMP [2.9.1, Restrictions]
11715   // The device expression must evaluate to a non-negative integer value.
11716   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
11717                                  /*StrictlyPositive=*/false))
11718     return nullptr;
11719 
11720   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11721   OpenMPDirectiveKind CaptureRegion =
11722       getOpenMPCaptureRegionForClause(DKind, OMPC_device);
11723   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11724     ValExpr = MakeFullExpr(ValExpr).get();
11725     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11726     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11727     HelperValStmt = buildPreInits(Context, Captures);
11728   }
11729 
11730   return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
11731                                        StartLoc, LParenLoc, EndLoc);
11732 }
11733 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)11734 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
11735                               DSAStackTy *Stack, QualType QTy,
11736                               bool FullCheck = true) {
11737   NamedDecl *ND;
11738   if (QTy->isIncompleteType(&ND)) {
11739     SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
11740     return false;
11741   }
11742   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
11743       !QTy.isTrivialType(SemaRef.Context))
11744     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
11745   return true;
11746 }
11747 
11748 /// Return true if it can be proven that the provided array expression
11749 /// (array section or array subscript) does NOT specify the whole size of the
11750 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)11751 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
11752                                                         const Expr *E,
11753                                                         QualType BaseQTy) {
11754   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11755 
11756   // If this is an array subscript, it refers to the whole size if the size of
11757   // the dimension is constant and equals 1. Also, an array section assumes the
11758   // format of an array subscript if no colon is used.
11759   if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11760     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11761       return ATy->getSize().getSExtValue() != 1;
11762     // Size can't be evaluated statically.
11763     return false;
11764   }
11765 
11766   assert(OASE && "Expecting array section if not an array subscript.");
11767   const Expr *LowerBound = OASE->getLowerBound();
11768   const Expr *Length = OASE->getLength();
11769 
11770   // If there is a lower bound that does not evaluates to zero, we are not
11771   // covering the whole dimension.
11772   if (LowerBound) {
11773     llvm::APSInt ConstLowerBound;
11774     if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
11775       return false; // Can't get the integer value as a constant.
11776     if (ConstLowerBound.getSExtValue())
11777       return true;
11778   }
11779 
11780   // If we don't have a length we covering the whole dimension.
11781   if (!Length)
11782     return false;
11783 
11784   // If the base is a pointer, we don't have a way to get the size of the
11785   // pointee.
11786   if (BaseQTy->isPointerType())
11787     return false;
11788 
11789   // We can only check if the length is the same as the size of the dimension
11790   // if we have a constant array.
11791   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
11792   if (!CATy)
11793     return false;
11794 
11795   llvm::APSInt ConstLength;
11796   if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11797     return false; // Can't get the integer value as a constant.
11798 
11799   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
11800 }
11801 
11802 // Return true if it can be proven that the provided array expression (array
11803 // section or array subscript) does NOT specify a single element of the array
11804 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)11805 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
11806                                                         const Expr *E,
11807                                                         QualType BaseQTy) {
11808   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11809 
11810   // An array subscript always refer to a single element. Also, an array section
11811   // assumes the format of an array subscript if no colon is used.
11812   if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11813     return false;
11814 
11815   assert(OASE && "Expecting array section if not an array subscript.");
11816   const Expr *Length = OASE->getLength();
11817 
11818   // If we don't have a length we have to check if the array has unitary size
11819   // for this dimension. Also, we should always expect a length if the base type
11820   // is pointer.
11821   if (!Length) {
11822     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11823       return ATy->getSize().getSExtValue() != 1;
11824     // We cannot assume anything.
11825     return false;
11826   }
11827 
11828   // Check if the length evaluates to 1.
11829   llvm::APSInt ConstLength;
11830   if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11831     return false; // Can't get the integer value as a constant.
11832 
11833   return ConstLength.getSExtValue() != 1;
11834 }
11835 
11836 // Return the expression of the base of the mappable expression or null if it
11837 // cannot be determined and do all the necessary checks to see if the expression
11838 // is valid as a standalone mappable expression. In the process, record all the
11839 // components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,bool NoDiagnose)11840 static const Expr *checkMapClauseExpressionBase(
11841     Sema &SemaRef, Expr *E,
11842     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
11843     OpenMPClauseKind CKind, bool NoDiagnose) {
11844   SourceLocation ELoc = E->getExprLoc();
11845   SourceRange ERange = E->getSourceRange();
11846 
11847   // The base of elements of list in a map clause have to be either:
11848   //  - a reference to variable or field.
11849   //  - a member expression.
11850   //  - an array expression.
11851   //
11852   // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
11853   // reference to 'r'.
11854   //
11855   // If we have:
11856   //
11857   // struct SS {
11858   //   Bla S;
11859   //   foo() {
11860   //     #pragma omp target map (S.Arr[:12]);
11861   //   }
11862   // }
11863   //
11864   // We want to retrieve the member expression 'this->S';
11865 
11866   const Expr *RelevantExpr = nullptr;
11867 
11868   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
11869   //  If a list item is an array section, it must specify contiguous storage.
11870   //
11871   // For this restriction it is sufficient that we make sure only references
11872   // to variables or fields and array expressions, and that no array sections
11873   // exist except in the rightmost expression (unless they cover the whole
11874   // dimension of the array). E.g. these would be invalid:
11875   //
11876   //   r.ArrS[3:5].Arr[6:7]
11877   //
11878   //   r.ArrS[3:5].x
11879   //
11880   // but these would be valid:
11881   //   r.ArrS[3].Arr[6:7]
11882   //
11883   //   r.ArrS[3].x
11884 
11885   bool AllowUnitySizeArraySection = true;
11886   bool AllowWholeSizeArraySection = true;
11887 
11888   while (!RelevantExpr) {
11889     E = E->IgnoreParenImpCasts();
11890 
11891     if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11892       if (!isa<VarDecl>(CurE->getDecl()))
11893         return nullptr;
11894 
11895       RelevantExpr = CurE;
11896 
11897       // If we got a reference to a declaration, we should not expect any array
11898       // section before that.
11899       AllowUnitySizeArraySection = false;
11900       AllowWholeSizeArraySection = false;
11901 
11902       // Record the component.
11903       CurComponents.emplace_back(CurE, CurE->getDecl());
11904     } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
11905       Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
11906 
11907       if (isa<CXXThisExpr>(BaseE))
11908         // We found a base expression: this->Val.
11909         RelevantExpr = CurE;
11910       else
11911         E = BaseE;
11912 
11913       if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11914         if (!NoDiagnose) {
11915           SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11916               << CurE->getSourceRange();
11917           return nullptr;
11918         }
11919         if (RelevantExpr)
11920           return nullptr;
11921         continue;
11922       }
11923 
11924       auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11925 
11926       // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
11927       //  A bit-field cannot appear in a map clause.
11928       //
11929       if (FD->isBitField()) {
11930         if (!NoDiagnose) {
11931           SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11932               << CurE->getSourceRange() << getOpenMPClauseName(CKind);
11933           return nullptr;
11934         }
11935         if (RelevantExpr)
11936           return nullptr;
11937         continue;
11938       }
11939 
11940       // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11941       //  If the type of a list item is a reference to a type T then the type
11942       //  will be considered to be T for all purposes of this clause.
11943       QualType CurType = BaseE->getType().getNonReferenceType();
11944 
11945       // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
11946       //  A list item cannot be a variable that is a member of a structure with
11947       //  a union type.
11948       //
11949       if (CurType->isUnionType()) {
11950         if (!NoDiagnose) {
11951           SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
11952               << CurE->getSourceRange();
11953           return nullptr;
11954         }
11955         continue;
11956       }
11957 
11958       // If we got a member expression, we should not expect any array section
11959       // before that:
11960       //
11961       // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
11962       //  If a list item is an element of a structure, only the rightmost symbol
11963       //  of the variable reference can be an array section.
11964       //
11965       AllowUnitySizeArraySection = false;
11966       AllowWholeSizeArraySection = false;
11967 
11968       // Record the component.
11969       CurComponents.emplace_back(CurE, FD);
11970     } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11971       E = CurE->getBase()->IgnoreParenImpCasts();
11972 
11973       if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
11974         if (!NoDiagnose) {
11975           SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11976               << 0 << CurE->getSourceRange();
11977           return nullptr;
11978         }
11979         continue;
11980       }
11981 
11982       // If we got an array subscript that express the whole dimension we
11983       // can have any array expressions before. If it only expressing part of
11984       // the dimension, we can only have unitary-size array expressions.
11985       if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
11986                                                       E->getType()))
11987         AllowWholeSizeArraySection = false;
11988 
11989       // Record the component - we don't have any declaration associated.
11990       CurComponents.emplace_back(CurE, nullptr);
11991     } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11992       assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
11993       E = CurE->getBase()->IgnoreParenImpCasts();
11994 
11995       QualType CurType =
11996           OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11997 
11998       // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11999       //  If the type of a list item is a reference to a type T then the type
12000       //  will be considered to be T for all purposes of this clause.
12001       if (CurType->isReferenceType())
12002         CurType = CurType->getPointeeType();
12003 
12004       bool IsPointer = CurType->isAnyPointerType();
12005 
12006       if (!IsPointer && !CurType->isArrayType()) {
12007         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12008             << 0 << CurE->getSourceRange();
12009         return nullptr;
12010       }
12011 
12012       bool NotWhole =
12013           checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
12014       bool NotUnity =
12015           checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
12016 
12017       if (AllowWholeSizeArraySection) {
12018         // Any array section is currently allowed. Allowing a whole size array
12019         // section implies allowing a unity array section as well.
12020         //
12021         // If this array section refers to the whole dimension we can still
12022         // accept other array sections before this one, except if the base is a
12023         // pointer. Otherwise, only unitary sections are accepted.
12024         if (NotWhole || IsPointer)
12025           AllowWholeSizeArraySection = false;
12026       } else if (AllowUnitySizeArraySection && NotUnity) {
12027         // A unity or whole array section is not allowed and that is not
12028         // compatible with the properties of the current array section.
12029         SemaRef.Diag(
12030             ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12031             << CurE->getSourceRange();
12032         return nullptr;
12033       }
12034 
12035       // Record the component - we don't have any declaration associated.
12036       CurComponents.emplace_back(CurE, nullptr);
12037     } else {
12038       if (!NoDiagnose) {
12039         // If nothing else worked, this is not a valid map clause expression.
12040         SemaRef.Diag(
12041             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12042             << ERange;
12043       }
12044       return nullptr;
12045     }
12046   }
12047 
12048   return RelevantExpr;
12049 }
12050 
12051 // Return true if expression E associated with value VD has conflicts with other
12052 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)12053 static bool checkMapConflicts(
12054     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
12055     bool CurrentRegionOnly,
12056     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
12057     OpenMPClauseKind CKind) {
12058   assert(VD && E);
12059   SourceLocation ELoc = E->getExprLoc();
12060   SourceRange ERange = E->getSourceRange();
12061 
12062   // In order to easily check the conflicts we need to match each component of
12063   // the expression under test with the components of the expressions that are
12064   // already in the stack.
12065 
12066   assert(!CurComponents.empty() && "Map clause expression with no components!");
12067   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12068          "Map clause expression with unexpected base!");
12069 
12070   // Variables to help detecting enclosing problems in data environment nests.
12071   bool IsEnclosedByDataEnvironmentExpr = false;
12072   const Expr *EnclosingExpr = nullptr;
12073 
12074   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12075       VD, CurrentRegionOnly,
12076       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12077        ERange, CKind, &EnclosingExpr,
12078        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
12079                           StackComponents,
12080                       OpenMPClauseKind) {
12081         assert(!StackComponents.empty() &&
12082                "Map clause expression with no components!");
12083         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12084                "Map clause expression with unexpected base!");
12085         (void)VD;
12086 
12087         // The whole expression in the stack.
12088         const Expr *RE = StackComponents.front().getAssociatedExpression();
12089 
12090         // Expressions must start from the same base. Here we detect at which
12091         // point both expressions diverge from each other and see if we can
12092         // detect if the memory referred to both expressions is contiguous and
12093         // do not overlap.
12094         auto CI = CurComponents.rbegin();
12095         auto CE = CurComponents.rend();
12096         auto SI = StackComponents.rbegin();
12097         auto SE = StackComponents.rend();
12098         for (; CI != CE && SI != SE; ++CI, ++SI) {
12099 
12100           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
12101           //  At most one list item can be an array item derived from a given
12102           //  variable in map clauses of the same construct.
12103           if (CurrentRegionOnly &&
12104               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12105                isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12106               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12107                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12108             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
12109                          diag::err_omp_multiple_array_items_in_map_clause)
12110                 << CI->getAssociatedExpression()->getSourceRange();
12111             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
12112                          diag::note_used_here)
12113                 << SI->getAssociatedExpression()->getSourceRange();
12114             return true;
12115           }
12116 
12117           // Do both expressions have the same kind?
12118           if (CI->getAssociatedExpression()->getStmtClass() !=
12119               SI->getAssociatedExpression()->getStmtClass())
12120             break;
12121 
12122           // Are we dealing with different variables/fields?
12123           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12124             break;
12125         }
12126         // Check if the extra components of the expressions in the enclosing
12127         // data environment are redundant for the current base declaration.
12128         // If they are, the maps completely overlap, which is legal.
12129         for (; SI != SE; ++SI) {
12130           QualType Type;
12131           if (const auto *ASE =
12132                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12133             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12134           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12135                          SI->getAssociatedExpression())) {
12136             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
12137             Type =
12138                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
12139           }
12140           if (Type.isNull() || Type->isAnyPointerType() ||
12141               checkArrayExpressionDoesNotReferToWholeSize(
12142                   SemaRef, SI->getAssociatedExpression(), Type))
12143             break;
12144         }
12145 
12146         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12147         //  List items of map clauses in the same construct must not share
12148         //  original storage.
12149         //
12150         // If the expressions are exactly the same or one is a subset of the
12151         // other, it means they are sharing storage.
12152         if (CI == CE && SI == SE) {
12153           if (CurrentRegionOnly) {
12154             if (CKind == OMPC_map) {
12155               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12156             } else {
12157               assert(CKind == OMPC_to || CKind == OMPC_from);
12158               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12159                   << ERange;
12160             }
12161             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12162                 << RE->getSourceRange();
12163             return true;
12164           }
12165           // If we find the same expression in the enclosing data environment,
12166           // that is legal.
12167           IsEnclosedByDataEnvironmentExpr = true;
12168           return false;
12169         }
12170 
12171         QualType DerivedType =
12172             std::prev(CI)->getAssociatedDeclaration()->getType();
12173         SourceLocation DerivedLoc =
12174             std::prev(CI)->getAssociatedExpression()->getExprLoc();
12175 
12176         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12177         //  If the type of a list item is a reference to a type T then the type
12178         //  will be considered to be T for all purposes of this clause.
12179         DerivedType = DerivedType.getNonReferenceType();
12180 
12181         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
12182         //  A variable for which the type is pointer and an array section
12183         //  derived from that variable must not appear as list items of map
12184         //  clauses of the same construct.
12185         //
12186         // Also, cover one of the cases in:
12187         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12188         //  If any part of the original storage of a list item has corresponding
12189         //  storage in the device data environment, all of the original storage
12190         //  must have corresponding storage in the device data environment.
12191         //
12192         if (DerivedType->isAnyPointerType()) {
12193           if (CI == CE || SI == SE) {
12194             SemaRef.Diag(
12195                 DerivedLoc,
12196                 diag::err_omp_pointer_mapped_along_with_derived_section)
12197                 << DerivedLoc;
12198             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12199                 << RE->getSourceRange();
12200             return true;
12201           }
12202           if (CI->getAssociatedExpression()->getStmtClass() !=
12203                          SI->getAssociatedExpression()->getStmtClass() ||
12204                      CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12205                          SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12206             assert(CI != CE && SI != SE);
12207             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12208                 << DerivedLoc;
12209             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12210                 << RE->getSourceRange();
12211             return true;
12212           }
12213         }
12214 
12215         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12216         //  List items of map clauses in the same construct must not share
12217         //  original storage.
12218         //
12219         // An expression is a subset of the other.
12220         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12221           if (CKind == OMPC_map) {
12222             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12223           } else {
12224             assert(CKind == OMPC_to || CKind == OMPC_from);
12225             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12226                 << ERange;
12227           }
12228           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12229               << RE->getSourceRange();
12230           return true;
12231         }
12232 
12233         // The current expression uses the same base as other expression in the
12234         // data environment but does not contain it completely.
12235         if (!CurrentRegionOnly && SI != SE)
12236           EnclosingExpr = RE;
12237 
12238         // The current expression is a subset of the expression in the data
12239         // environment.
12240         IsEnclosedByDataEnvironmentExpr |=
12241             (!CurrentRegionOnly && CI != CE && SI == SE);
12242 
12243         return false;
12244       });
12245 
12246   if (CurrentRegionOnly)
12247     return FoundError;
12248 
12249   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12250   //  If any part of the original storage of a list item has corresponding
12251   //  storage in the device data environment, all of the original storage must
12252   //  have corresponding storage in the device data environment.
12253   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
12254   //  If a list item is an element of a structure, and a different element of
12255   //  the structure has a corresponding list item in the device data environment
12256   //  prior to a task encountering the construct associated with the map clause,
12257   //  then the list item must also have a corresponding list item in the device
12258   //  data environment prior to the task encountering the construct.
12259   //
12260   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12261     SemaRef.Diag(ELoc,
12262                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
12263         << ERange;
12264     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
12265         << EnclosingExpr->getSourceRange();
12266     return true;
12267   }
12268 
12269   return FoundError;
12270 }
12271 
12272 namespace {
12273 // Utility struct that gathers all the related lists associated with a mappable
12274 // expression.
12275 struct MappableVarListInfo {
12276   // The list of expressions.
12277   ArrayRef<Expr *> VarList;
12278   // The list of processed expressions.
12279   SmallVector<Expr *, 16> ProcessedVarList;
12280   // The mappble components for each expression.
12281   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
12282   // The base declaration of the variable.
12283   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
12284 
MappableVarListInfo__anon0050f7f03511::MappableVarListInfo12285   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
12286     // We have a list of components and base declarations for each entry in the
12287     // variable list.
12288     VarComponents.reserve(VarList.size());
12289     VarBaseDeclarations.reserve(VarList.size());
12290   }
12291 };
12292 }
12293 
12294 // Check the validity of the provided variable list for the provided clause kind
12295 // \a CKind. In the check process the valid expressions, and mappable expression
12296 // components and variables are extracted and used to fill \a Vars,
12297 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
12298 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
12299 static void
checkMappableExpressionList(Sema & SemaRef,DSAStackTy * DSAS,OpenMPClauseKind CKind,MappableVarListInfo & MVLI,SourceLocation StartLoc,OpenMPMapClauseKind MapType=OMPC_MAP_unknown,bool IsMapTypeImplicit=false)12300 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
12301                             OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
12302                             SourceLocation StartLoc,
12303                             OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
12304                             bool IsMapTypeImplicit = false) {
12305   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
12306   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12307          "Unexpected clause kind with mappable expressions!");
12308 
12309   // Keep track of the mappable components and base declarations in this clause.
12310   // Each entry in the list is going to have a list of components associated. We
12311   // record each set of the components so that we can build the clause later on.
12312   // In the end we should have the same amount of declarations and component
12313   // lists.
12314 
12315   for (Expr *RE : MVLI.VarList) {
12316     assert(RE && "Null expr in omp to/from/map clause");
12317     SourceLocation ELoc = RE->getExprLoc();
12318 
12319     const Expr *VE = RE->IgnoreParenLValueCasts();
12320 
12321     if (VE->isValueDependent() || VE->isTypeDependent() ||
12322         VE->isInstantiationDependent() ||
12323         VE->containsUnexpandedParameterPack()) {
12324       // We can only analyze this information once the missing information is
12325       // resolved.
12326       MVLI.ProcessedVarList.push_back(RE);
12327       continue;
12328     }
12329 
12330     Expr *SimpleExpr = RE->IgnoreParenCasts();
12331 
12332     if (!RE->IgnoreParenImpCasts()->isLValue()) {
12333       SemaRef.Diag(ELoc,
12334                    diag::err_omp_expected_named_var_member_or_array_expression)
12335           << RE->getSourceRange();
12336       continue;
12337     }
12338 
12339     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
12340     ValueDecl *CurDeclaration = nullptr;
12341 
12342     // Obtain the array or member expression bases if required. Also, fill the
12343     // components array with all the components identified in the process.
12344     const Expr *BE = checkMapClauseExpressionBase(
12345         SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
12346     if (!BE)
12347       continue;
12348 
12349     assert(!CurComponents.empty() &&
12350            "Invalid mappable expression information.");
12351 
12352     // For the following checks, we rely on the base declaration which is
12353     // expected to be associated with the last component. The declaration is
12354     // expected to be a variable or a field (if 'this' is being mapped).
12355     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12356     assert(CurDeclaration && "Null decl on map clause.");
12357     assert(
12358         CurDeclaration->isCanonicalDecl() &&
12359         "Expecting components to have associated only canonical declarations.");
12360 
12361     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12362     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12363 
12364     assert((VD || FD) && "Only variables or fields are expected here!");
12365     (void)FD;
12366 
12367     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12368     // threadprivate variables cannot appear in a map clause.
12369     // OpenMP 4.5 [2.10.5, target update Construct]
12370     // threadprivate variables cannot appear in a from clause.
12371     if (VD && DSAS->isThreadPrivate(VD)) {
12372       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
12373       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12374           << getOpenMPClauseName(CKind);
12375       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
12376       continue;
12377     }
12378 
12379     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12380     //  A list item cannot appear in both a map clause and a data-sharing
12381     //  attribute clause on the same construct.
12382 
12383     // Check conflicts with other map clause expressions. We check the conflicts
12384     // with the current construct separately from the enclosing data
12385     // environment, because the restrictions are different. We only have to
12386     // check conflicts across regions for the map clauses.
12387     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12388                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
12389       break;
12390     if (CKind == OMPC_map &&
12391         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12392                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
12393       break;
12394 
12395     // OpenMP 4.5 [2.10.5, target update Construct]
12396     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12397     //  If the type of a list item is a reference to a type T then the type will
12398     //  be considered to be T for all purposes of this clause.
12399     auto I = llvm::find_if(
12400         CurComponents,
12401         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
12402           return MC.getAssociatedDeclaration();
12403         });
12404     assert(I != CurComponents.end() && "Null decl on map clause.");
12405     QualType Type =
12406         I->getAssociatedDeclaration()->getType().getNonReferenceType();
12407 
12408     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
12409     // A list item in a to or from clause must have a mappable type.
12410     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12411     //  A list item must have a mappable type.
12412     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
12413                            DSAS, Type))
12414       continue;
12415 
12416     if (CKind == OMPC_map) {
12417       // target enter data
12418       // OpenMP [2.10.2, Restrictions, p. 99]
12419       // A map-type must be specified in all map clauses and must be either
12420       // to or alloc.
12421       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
12422       if (DKind == OMPD_target_enter_data &&
12423           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12424         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12425             << (IsMapTypeImplicit ? 1 : 0)
12426             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12427             << getOpenMPDirectiveName(DKind);
12428         continue;
12429       }
12430 
12431       // target exit_data
12432       // OpenMP [2.10.3, Restrictions, p. 102]
12433       // A map-type must be specified in all map clauses and must be either
12434       // from, release, or delete.
12435       if (DKind == OMPD_target_exit_data &&
12436           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12437             MapType == OMPC_MAP_delete)) {
12438         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12439             << (IsMapTypeImplicit ? 1 : 0)
12440             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12441             << getOpenMPDirectiveName(DKind);
12442         continue;
12443       }
12444 
12445       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12446       // A list item cannot appear in both a map clause and a data-sharing
12447       // attribute clause on the same construct
12448       if (VD && isOpenMPTargetExecutionDirective(DKind)) {
12449         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
12450         if (isOpenMPPrivate(DVar.CKind)) {
12451           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12452               << getOpenMPClauseName(DVar.CKind)
12453               << getOpenMPClauseName(OMPC_map)
12454               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
12455           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
12456           continue;
12457         }
12458       }
12459     }
12460 
12461     // Save the current expression.
12462     MVLI.ProcessedVarList.push_back(RE);
12463 
12464     // Store the components in the stack so that they can be used to check
12465     // against other clauses later on.
12466     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12467                                           /*WhereFoundClauseKind=*/OMPC_map);
12468 
12469     // Save the components and declaration to create the clause. For purposes of
12470     // the clause creation, any component list that has has base 'this' uses
12471     // null as base declaration.
12472     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12473     MVLI.VarComponents.back().append(CurComponents.begin(),
12474                                      CurComponents.end());
12475     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
12476                                                            : CurDeclaration);
12477   }
12478 }
12479 
12480 OMPClause *
ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12481 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
12482                            OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
12483                            SourceLocation MapLoc, SourceLocation ColonLoc,
12484                            ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12485                            SourceLocation LParenLoc, SourceLocation EndLoc) {
12486   MappableVarListInfo MVLI(VarList);
12487   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
12488                               MapType, IsMapTypeImplicit);
12489 
12490   // We need to produce a map clause even if we don't have variables so that
12491   // other diagnostics related with non-existing map clauses are accurate.
12492   return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12493                               MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12494                               MVLI.VarComponents, MapTypeModifier, MapType,
12495                               IsMapTypeImplicit, MapLoc);
12496 }
12497 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)12498 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
12499                                                TypeResult ParsedType) {
12500   assert(ParsedType.isUsable());
12501 
12502   QualType ReductionType = GetTypeFromParser(ParsedType.get());
12503   if (ReductionType.isNull())
12504     return QualType();
12505 
12506   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
12507   // A type name in a declare reduction directive cannot be a function type, an
12508   // array type, a reference type, or a type qualified with const, volatile or
12509   // restrict.
12510   if (ReductionType.hasQualifiers()) {
12511     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12512     return QualType();
12513   }
12514 
12515   if (ReductionType->isFunctionType()) {
12516     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12517     return QualType();
12518   }
12519   if (ReductionType->isReferenceType()) {
12520     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12521     return QualType();
12522   }
12523   if (ReductionType->isArrayType()) {
12524     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12525     return QualType();
12526   }
12527   return ReductionType;
12528 }
12529 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)12530 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
12531     Scope *S, DeclContext *DC, DeclarationName Name,
12532     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12533     AccessSpecifier AS, Decl *PrevDeclInScope) {
12534   SmallVector<Decl *, 8> Decls;
12535   Decls.reserve(ReductionTypes.size());
12536 
12537   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
12538                       forRedeclarationInCurContext());
12539   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
12540   // A reduction-identifier may not be re-declared in the current scope for the
12541   // same type or for a type that is compatible according to the base language
12542   // rules.
12543   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12544   OMPDeclareReductionDecl *PrevDRD = nullptr;
12545   bool InCompoundScope = true;
12546   if (S != nullptr) {
12547     // Find previous declaration with the same name not referenced in other
12548     // declarations.
12549     FunctionScopeInfo *ParentFn = getEnclosingFunction();
12550     InCompoundScope =
12551         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
12552     LookupName(Lookup, S);
12553     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
12554                          /*AllowInlineNamespace=*/false);
12555     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12556     LookupResult::Filter Filter = Lookup.makeFilter();
12557     while (Filter.hasNext()) {
12558       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12559       if (InCompoundScope) {
12560         auto I = UsedAsPrevious.find(PrevDecl);
12561         if (I == UsedAsPrevious.end())
12562           UsedAsPrevious[PrevDecl] = false;
12563         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
12564           UsedAsPrevious[D] = true;
12565       }
12566       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12567           PrevDecl->getLocation();
12568     }
12569     Filter.done();
12570     if (InCompoundScope) {
12571       for (const auto &PrevData : UsedAsPrevious) {
12572         if (!PrevData.second) {
12573           PrevDRD = PrevData.first;
12574           break;
12575         }
12576       }
12577     }
12578   } else if (PrevDeclInScope != nullptr) {
12579     auto *PrevDRDInScope = PrevDRD =
12580         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12581     do {
12582       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12583           PrevDRDInScope->getLocation();
12584       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12585     } while (PrevDRDInScope != nullptr);
12586   }
12587   for (const auto &TyData : ReductionTypes) {
12588     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12589     bool Invalid = false;
12590     if (I != PreviousRedeclTypes.end()) {
12591       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12592           << TyData.first;
12593       Diag(I->second, diag::note_previous_definition);
12594       Invalid = true;
12595     }
12596     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12597     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
12598                                                 Name, TyData.first, PrevDRD);
12599     DC->addDecl(DRD);
12600     DRD->setAccess(AS);
12601     Decls.push_back(DRD);
12602     if (Invalid)
12603       DRD->setInvalidDecl();
12604     else
12605       PrevDRD = DRD;
12606   }
12607 
12608   return DeclGroupPtrTy::make(
12609       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
12610 }
12611 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)12612 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
12613   auto *DRD = cast<OMPDeclareReductionDecl>(D);
12614 
12615   // Enter new function scope.
12616   PushFunctionScope();
12617   setFunctionHasBranchProtectedScope();
12618   getCurFunction()->setHasOMPDeclareReductionCombiner();
12619 
12620   if (S != nullptr)
12621     PushDeclContext(S, DRD);
12622   else
12623     CurContext = DRD;
12624 
12625   PushExpressionEvaluationContext(
12626       ExpressionEvaluationContext::PotentiallyEvaluated);
12627 
12628   QualType ReductionType = DRD->getType();
12629   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
12630   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
12631   // uses semantics of argument handles by value, but it should be passed by
12632   // reference. C lang does not support references, so pass all parameters as
12633   // pointers.
12634   // Create 'T omp_in;' variable.
12635   VarDecl *OmpInParm =
12636       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
12637   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
12638   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
12639   // uses semantics of argument handles by value, but it should be passed by
12640   // reference. C lang does not support references, so pass all parameters as
12641   // pointers.
12642   // Create 'T omp_out;' variable.
12643   VarDecl *OmpOutParm =
12644       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
12645   if (S != nullptr) {
12646     PushOnScopeChains(OmpInParm, S);
12647     PushOnScopeChains(OmpOutParm, S);
12648   } else {
12649     DRD->addDecl(OmpInParm);
12650     DRD->addDecl(OmpOutParm);
12651   }
12652 }
12653 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)12654 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
12655   auto *DRD = cast<OMPDeclareReductionDecl>(D);
12656   DiscardCleanupsInEvaluationContext();
12657   PopExpressionEvaluationContext();
12658 
12659   PopDeclContext();
12660   PopFunctionScopeInfo();
12661 
12662   if (Combiner != nullptr)
12663     DRD->setCombiner(Combiner);
12664   else
12665     DRD->setInvalidDecl();
12666 }
12667 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)12668 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
12669   auto *DRD = cast<OMPDeclareReductionDecl>(D);
12670 
12671   // Enter new function scope.
12672   PushFunctionScope();
12673   setFunctionHasBranchProtectedScope();
12674 
12675   if (S != nullptr)
12676     PushDeclContext(S, DRD);
12677   else
12678     CurContext = DRD;
12679 
12680   PushExpressionEvaluationContext(
12681       ExpressionEvaluationContext::PotentiallyEvaluated);
12682 
12683   QualType ReductionType = DRD->getType();
12684   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
12685   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
12686   // uses semantics of argument handles by value, but it should be passed by
12687   // reference. C lang does not support references, so pass all parameters as
12688   // pointers.
12689   // Create 'T omp_priv;' variable.
12690   VarDecl *OmpPrivParm =
12691       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
12692   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
12693   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
12694   // uses semantics of argument handles by value, but it should be passed by
12695   // reference. C lang does not support references, so pass all parameters as
12696   // pointers.
12697   // Create 'T omp_orig;' variable.
12698   VarDecl *OmpOrigParm =
12699       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
12700   if (S != nullptr) {
12701     PushOnScopeChains(OmpPrivParm, S);
12702     PushOnScopeChains(OmpOrigParm, S);
12703   } else {
12704     DRD->addDecl(OmpPrivParm);
12705     DRD->addDecl(OmpOrigParm);
12706   }
12707   return OmpPrivParm;
12708 }
12709 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)12710 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
12711                                                      VarDecl *OmpPrivParm) {
12712   auto *DRD = cast<OMPDeclareReductionDecl>(D);
12713   DiscardCleanupsInEvaluationContext();
12714   PopExpressionEvaluationContext();
12715 
12716   PopDeclContext();
12717   PopFunctionScopeInfo();
12718 
12719   if (Initializer != nullptr) {
12720     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
12721   } else if (OmpPrivParm->hasInit()) {
12722     DRD->setInitializer(OmpPrivParm->getInit(),
12723                         OmpPrivParm->isDirectInit()
12724                             ? OMPDeclareReductionDecl::DirectInit
12725                             : OMPDeclareReductionDecl::CopyInit);
12726   } else {
12727     DRD->setInvalidDecl();
12728   }
12729 }
12730 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)12731 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
12732     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
12733   for (Decl *D : DeclReductions.get()) {
12734     if (IsValid) {
12735       if (S)
12736         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
12737                           /*AddToContext=*/false);
12738     } else {
12739       D->setInvalidDecl();
12740     }
12741   }
12742   return DeclReductions;
12743 }
12744 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12745 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
12746                                            SourceLocation StartLoc,
12747                                            SourceLocation LParenLoc,
12748                                            SourceLocation EndLoc) {
12749   Expr *ValExpr = NumTeams;
12750   Stmt *HelperValStmt = nullptr;
12751 
12752   // OpenMP [teams Constrcut, Restrictions]
12753   // The num_teams expression must evaluate to a positive integer value.
12754   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
12755                                  /*StrictlyPositive=*/true))
12756     return nullptr;
12757 
12758   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12759   OpenMPDirectiveKind CaptureRegion =
12760       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
12761   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12762     ValExpr = MakeFullExpr(ValExpr).get();
12763     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12764     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12765     HelperValStmt = buildPreInits(Context, Captures);
12766   }
12767 
12768   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
12769                                          StartLoc, LParenLoc, EndLoc);
12770 }
12771 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12772 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
12773                                               SourceLocation StartLoc,
12774                                               SourceLocation LParenLoc,
12775                                               SourceLocation EndLoc) {
12776   Expr *ValExpr = ThreadLimit;
12777   Stmt *HelperValStmt = nullptr;
12778 
12779   // OpenMP [teams Constrcut, Restrictions]
12780   // The thread_limit expression must evaluate to a positive integer value.
12781   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
12782                                  /*StrictlyPositive=*/true))
12783     return nullptr;
12784 
12785   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12786   OpenMPDirectiveKind CaptureRegion =
12787       getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
12788   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12789     ValExpr = MakeFullExpr(ValExpr).get();
12790     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12791     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12792     HelperValStmt = buildPreInits(Context, Captures);
12793   }
12794 
12795   return new (Context) OMPThreadLimitClause(
12796       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12797 }
12798 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12799 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
12800                                            SourceLocation StartLoc,
12801                                            SourceLocation LParenLoc,
12802                                            SourceLocation EndLoc) {
12803   Expr *ValExpr = Priority;
12804 
12805   // OpenMP [2.9.1, task Constrcut]
12806   // The priority-value is a non-negative numerical scalar expression.
12807   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
12808                                  /*StrictlyPositive=*/false))
12809     return nullptr;
12810 
12811   return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12812 }
12813 
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12814 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
12815                                             SourceLocation StartLoc,
12816                                             SourceLocation LParenLoc,
12817                                             SourceLocation EndLoc) {
12818   Expr *ValExpr = Grainsize;
12819 
12820   // OpenMP [2.9.2, taskloop Constrcut]
12821   // The parameter of the grainsize clause must be a positive integer
12822   // expression.
12823   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
12824                                  /*StrictlyPositive=*/true))
12825     return nullptr;
12826 
12827   return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12828 }
12829 
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12830 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
12831                                            SourceLocation StartLoc,
12832                                            SourceLocation LParenLoc,
12833                                            SourceLocation EndLoc) {
12834   Expr *ValExpr = NumTasks;
12835 
12836   // OpenMP [2.9.2, taskloop Constrcut]
12837   // The parameter of the num_tasks clause must be a positive integer
12838   // expression.
12839   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
12840                                  /*StrictlyPositive=*/true))
12841     return nullptr;
12842 
12843   return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12844 }
12845 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12846 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
12847                                        SourceLocation LParenLoc,
12848                                        SourceLocation EndLoc) {
12849   // OpenMP [2.13.2, critical construct, Description]
12850   // ... where hint-expression is an integer constant expression that evaluates
12851   // to a valid lock hint.
12852   ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12853   if (HintExpr.isInvalid())
12854     return nullptr;
12855   return new (Context)
12856       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
12857 }
12858 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)12859 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
12860     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12861     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
12862     SourceLocation EndLoc) {
12863   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
12864     std::string Values;
12865     Values += "'";
12866     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
12867     Values += "'";
12868     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12869         << Values << getOpenMPClauseName(OMPC_dist_schedule);
12870     return nullptr;
12871   }
12872   Expr *ValExpr = ChunkSize;
12873   Stmt *HelperValStmt = nullptr;
12874   if (ChunkSize) {
12875     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12876         !ChunkSize->isInstantiationDependent() &&
12877         !ChunkSize->containsUnexpandedParameterPack()) {
12878       SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
12879       ExprResult Val =
12880           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12881       if (Val.isInvalid())
12882         return nullptr;
12883 
12884       ValExpr = Val.get();
12885 
12886       // OpenMP [2.7.1, Restrictions]
12887       //  chunk_size must be a loop invariant integer expression with a positive
12888       //  value.
12889       llvm::APSInt Result;
12890       if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12891         if (Result.isSigned() && !Result.isStrictlyPositive()) {
12892           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12893               << "dist_schedule" << ChunkSize->getSourceRange();
12894           return nullptr;
12895         }
12896       } else if (getOpenMPCaptureRegionForClause(
12897                      DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12898                      OMPD_unknown &&
12899                  !CurContext->isDependentContext()) {
12900         ValExpr = MakeFullExpr(ValExpr).get();
12901         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12902         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12903         HelperValStmt = buildPreInits(Context, Captures);
12904       }
12905     }
12906   }
12907 
12908   return new (Context)
12909       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
12910                             Kind, ValExpr, HelperValStmt);
12911 }
12912 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)12913 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
12914     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
12915     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
12916     SourceLocation KindLoc, SourceLocation EndLoc) {
12917   // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
12918   if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12919     std::string Value;
12920     SourceLocation Loc;
12921     Value += "'";
12922     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12923       Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12924                                              OMPC_DEFAULTMAP_MODIFIER_tofrom);
12925       Loc = MLoc;
12926     } else {
12927       Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12928                                              OMPC_DEFAULTMAP_scalar);
12929       Loc = KindLoc;
12930     }
12931     Value += "'";
12932     Diag(Loc, diag::err_omp_unexpected_clause_value)
12933         << Value << getOpenMPClauseName(OMPC_defaultmap);
12934     return nullptr;
12935   }
12936   DSAStack->setDefaultDMAToFromScalar(StartLoc);
12937 
12938   return new (Context)
12939       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
12940 }
12941 
ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)12942 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
12943   DeclContext *CurLexicalContext = getCurLexicalContext();
12944   if (!CurLexicalContext->isFileContext() &&
12945       !CurLexicalContext->isExternCContext() &&
12946       !CurLexicalContext->isExternCXXContext() &&
12947       !isa<CXXRecordDecl>(CurLexicalContext) &&
12948       !isa<ClassTemplateDecl>(CurLexicalContext) &&
12949       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12950       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12951     Diag(Loc, diag::err_omp_region_not_file_context);
12952     return false;
12953   }
12954   if (IsInOpenMPDeclareTargetContext) {
12955     Diag(Loc, diag::err_omp_enclosed_declare_target);
12956     return false;
12957   }
12958 
12959   IsInOpenMPDeclareTargetContext = true;
12960   return true;
12961 }
12962 
ActOnFinishOpenMPDeclareTargetDirective()12963 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
12964   assert(IsInOpenMPDeclareTargetContext &&
12965          "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12966   IsInOpenMPDeclareTargetContext = false;
12967 }
12968 
ActOnOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OMPDeclareTargetDeclAttr::MapTypeTy MT,NamedDeclSetType & SameDirectiveDecls)12969 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
12970                                         CXXScopeSpec &ScopeSpec,
12971                                         const DeclarationNameInfo &Id,
12972                                         OMPDeclareTargetDeclAttr::MapTypeTy MT,
12973                                         NamedDeclSetType &SameDirectiveDecls) {
12974   LookupResult Lookup(*this, Id, LookupOrdinaryName);
12975   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
12976 
12977   if (Lookup.isAmbiguous())
12978     return;
12979   Lookup.suppressDiagnostics();
12980 
12981   if (!Lookup.isSingleResult()) {
12982     if (TypoCorrection Corrected =
12983             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
12984                         llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
12985                         CTK_ErrorRecovery)) {
12986       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12987                                   << Id.getName());
12988       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
12989       return;
12990     }
12991 
12992     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
12993     return;
12994   }
12995 
12996   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
12997   if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12998     if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
12999       Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
13000     if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
13001       auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13002       ND->addAttr(A);
13003       if (ASTMutationListener *ML = Context.getASTMutationListener())
13004         ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13005       checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
13006     } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
13007       Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
13008           << Id.getName();
13009     }
13010   } else {
13011     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
13012   }
13013 }
13014 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)13015 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
13016                                      Sema &SemaRef, Decl *D) {
13017   if (!D)
13018     return;
13019   const Decl *LD = nullptr;
13020   if (isa<TagDecl>(D)) {
13021     LD = cast<TagDecl>(D)->getDefinition();
13022   } else if (isa<VarDecl>(D)) {
13023     LD = cast<VarDecl>(D)->getDefinition();
13024 
13025     // If this is an implicit variable that is legal and we do not need to do
13026     // anything.
13027     if (cast<VarDecl>(D)->isImplicit()) {
13028       auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13029           SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
13030       D->addAttr(A);
13031       if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
13032         ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13033       return;
13034     }
13035   } else if (const auto *F = dyn_cast<FunctionDecl>(D)) {
13036     const FunctionDecl *FD = nullptr;
13037     if (cast<FunctionDecl>(D)->hasBody(FD)) {
13038       LD = FD;
13039       // If the definition is associated with the current declaration in the
13040       // target region (it can be e.g. a lambda) that is legal and we do not
13041       // need to do anything else.
13042       if (LD == D) {
13043         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13044             SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
13045         D->addAttr(A);
13046         if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
13047           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13048         return;
13049       }
13050     } else if (F->isFunctionTemplateSpecialization() &&
13051                F->getTemplateSpecializationKind() ==
13052                    TSK_ImplicitInstantiation) {
13053       // Check if the function is implicitly instantiated from the template
13054       // defined in the declare target region.
13055       const FunctionTemplateDecl *FTD = F->getPrimaryTemplate();
13056       if (FTD && FTD->hasAttr<OMPDeclareTargetDeclAttr>())
13057         return;
13058     }
13059   }
13060   if (!LD)
13061     LD = D;
13062   if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
13063       ((isa<VarDecl>(LD) && !isa<ParmVarDecl>(LD)) || isa<FunctionDecl>(LD))) {
13064     // Outlined declaration is not declared target.
13065     if (!isa<FunctionDecl>(LD)) {
13066       if (LD->isOutOfLine()) {
13067         SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
13068         SemaRef.Diag(SL, diag::note_used_here) << SR;
13069       } else {
13070         const DeclContext *DC = LD->getDeclContext();
13071         while (DC &&
13072                (!isa<FunctionDecl>(DC) ||
13073                 !cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()))
13074           DC = DC->getParent();
13075         if (DC)
13076           return;
13077 
13078         // Is not declared in target context.
13079         SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
13080         SemaRef.Diag(SL, diag::note_used_here) << SR;
13081       }
13082     }
13083     // Mark decl as declared target to prevent further diagnostic.
13084     auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13085         SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
13086     D->addAttr(A);
13087     if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
13088       ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13089   }
13090 }
13091 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)13092 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
13093                                    Sema &SemaRef, DSAStackTy *Stack,
13094                                    ValueDecl *VD) {
13095   return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13096          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
13097                            /*FullCheck=*/false);
13098 }
13099 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)13100 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
13101                                             SourceLocation IdLoc) {
13102   if (!D || D->isInvalidDecl())
13103     return;
13104   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
13105   SourceLocation SL = E ? E->getLocStart() : D->getLocation();
13106   if (auto *VD = dyn_cast<VarDecl>(D)) {
13107     // Only global variables can be marked as declare target.
13108     if (VD->isLocalVarDeclOrParm())
13109       return;
13110     // 2.10.6: threadprivate variable cannot appear in a declare target
13111     // directive.
13112     if (DSAStack->isThreadPrivate(VD)) {
13113       Diag(SL, diag::err_omp_threadprivate_in_target);
13114       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
13115       return;
13116     }
13117   }
13118   if (auto *VD = dyn_cast<ValueDecl>(D)) {
13119     // Problem if any with var declared with incomplete type will be reported
13120     // as normal, so no need to check it here.
13121     if ((E || !VD->getType()->isIncompleteType()) &&
13122         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
13123       // Mark decl as declared target to prevent further diagnostic.
13124       if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD) ||
13125           isa<FunctionTemplateDecl>(VD)) {
13126         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13127             Context, OMPDeclareTargetDeclAttr::MT_To);
13128         VD->addAttr(A);
13129         if (ASTMutationListener *ML = Context.getASTMutationListener())
13130           ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
13131       }
13132       return;
13133     }
13134   }
13135   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13136     D = FTD->getTemplatedDecl();
13137   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
13138     if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
13139         (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
13140          OMPDeclareTargetDeclAttr::MT_Link)) {
13141       assert(IdLoc.isValid() && "Source location is expected");
13142       Diag(IdLoc, diag::err_omp_function_in_link_clause);
13143       Diag(FD->getLocation(), diag::note_defined_here) << FD;
13144       return;
13145     }
13146   }
13147   if (!E) {
13148     // Checking declaration inside declare target region.
13149     if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
13150         (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13151          isa<FunctionTemplateDecl>(D))) {
13152       auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13153           Context, OMPDeclareTargetDeclAttr::MT_To);
13154       D->addAttr(A);
13155       if (ASTMutationListener *ML = Context.getASTMutationListener())
13156         ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13157     }
13158     return;
13159   }
13160   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
13161 }
13162 
ActOnOpenMPToClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13163 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
13164                                      SourceLocation StartLoc,
13165                                      SourceLocation LParenLoc,
13166                                      SourceLocation EndLoc) {
13167   MappableVarListInfo MVLI(VarList);
13168   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
13169   if (MVLI.ProcessedVarList.empty())
13170     return nullptr;
13171 
13172   return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13173                              MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13174                              MVLI.VarComponents);
13175 }
13176 
ActOnOpenMPFromClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13177 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
13178                                        SourceLocation StartLoc,
13179                                        SourceLocation LParenLoc,
13180                                        SourceLocation EndLoc) {
13181   MappableVarListInfo MVLI(VarList);
13182   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
13183   if (MVLI.ProcessedVarList.empty())
13184     return nullptr;
13185 
13186   return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13187                                MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13188                                MVLI.VarComponents);
13189 }
13190 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13191 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
13192                                                SourceLocation StartLoc,
13193                                                SourceLocation LParenLoc,
13194                                                SourceLocation EndLoc) {
13195   MappableVarListInfo MVLI(VarList);
13196   SmallVector<Expr *, 8> PrivateCopies;
13197   SmallVector<Expr *, 8> Inits;
13198 
13199   for (Expr *RefExpr : VarList) {
13200     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
13201     SourceLocation ELoc;
13202     SourceRange ERange;
13203     Expr *SimpleRefExpr = RefExpr;
13204     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13205     if (Res.second) {
13206       // It will be analyzed later.
13207       MVLI.ProcessedVarList.push_back(RefExpr);
13208       PrivateCopies.push_back(nullptr);
13209       Inits.push_back(nullptr);
13210     }
13211     ValueDecl *D = Res.first;
13212     if (!D)
13213       continue;
13214 
13215     QualType Type = D->getType();
13216     Type = Type.getNonReferenceType().getUnqualifiedType();
13217 
13218     auto *VD = dyn_cast<VarDecl>(D);
13219 
13220     // Item should be a pointer or reference to pointer.
13221     if (!Type->isPointerType()) {
13222       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13223           << 0 << RefExpr->getSourceRange();
13224       continue;
13225     }
13226 
13227     // Build the private variable and the expression that refers to it.
13228     auto VDPrivate =
13229         buildVarDecl(*this, ELoc, Type, D->getName(),
13230                      D->hasAttrs() ? &D->getAttrs() : nullptr,
13231                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13232     if (VDPrivate->isInvalidDecl())
13233       continue;
13234 
13235     CurContext->addDecl(VDPrivate);
13236     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13237         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13238 
13239     // Add temporary variable to initialize the private copy of the pointer.
13240     VarDecl *VDInit =
13241         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
13242     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
13243         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13244     AddInitializerToDecl(VDPrivate,
13245                          DefaultLvalueConversion(VDInitRefExpr).get(),
13246                          /*DirectInit=*/false);
13247 
13248     // If required, build a capture to implement the privatization initialized
13249     // with the current list item value.
13250     DeclRefExpr *Ref = nullptr;
13251     if (!VD)
13252       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13253     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13254     PrivateCopies.push_back(VDPrivateRefExpr);
13255     Inits.push_back(VDInitRefExpr);
13256 
13257     // We need to add a data sharing attribute for this variable to make sure it
13258     // is correctly captured. A variable that shows up in a use_device_ptr has
13259     // similar properties of a first private variable.
13260     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13261 
13262     // Create a mappable component for the list item. List items in this clause
13263     // only need a component.
13264     MVLI.VarBaseDeclarations.push_back(D);
13265     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13266     MVLI.VarComponents.back().push_back(
13267         OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
13268   }
13269 
13270   if (MVLI.ProcessedVarList.empty())
13271     return nullptr;
13272 
13273   return OMPUseDevicePtrClause::Create(
13274       Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13275       PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13276 }
13277 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13278 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
13279                                               SourceLocation StartLoc,
13280                                               SourceLocation LParenLoc,
13281                                               SourceLocation EndLoc) {
13282   MappableVarListInfo MVLI(VarList);
13283   for (Expr *RefExpr : VarList) {
13284     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
13285     SourceLocation ELoc;
13286     SourceRange ERange;
13287     Expr *SimpleRefExpr = RefExpr;
13288     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13289     if (Res.second) {
13290       // It will be analyzed later.
13291       MVLI.ProcessedVarList.push_back(RefExpr);
13292     }
13293     ValueDecl *D = Res.first;
13294     if (!D)
13295       continue;
13296 
13297     QualType Type = D->getType();
13298     // item should be a pointer or array or reference to pointer or array
13299     if (!Type.getNonReferenceType()->isPointerType() &&
13300         !Type.getNonReferenceType()->isArrayType()) {
13301       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13302           << 0 << RefExpr->getSourceRange();
13303       continue;
13304     }
13305 
13306     // Check if the declaration in the clause does not show up in any data
13307     // sharing attribute.
13308     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13309     if (isOpenMPPrivate(DVar.CKind)) {
13310       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13311           << getOpenMPClauseName(DVar.CKind)
13312           << getOpenMPClauseName(OMPC_is_device_ptr)
13313           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
13314       reportOriginalDsa(*this, DSAStack, D, DVar);
13315       continue;
13316     }
13317 
13318     const Expr *ConflictExpr;
13319     if (DSAStack->checkMappableExprComponentListsForDecl(
13320             D, /*CurrentRegionOnly=*/true,
13321             [&ConflictExpr](
13322                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
13323                 OpenMPClauseKind) -> bool {
13324               ConflictExpr = R.front().getAssociatedExpression();
13325               return true;
13326             })) {
13327       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13328       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
13329           << ConflictExpr->getSourceRange();
13330       continue;
13331     }
13332 
13333     // Store the components in the stack so that they can be used to check
13334     // against other clauses later on.
13335     OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
13336     DSAStack->addMappableExpressionComponents(
13337         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
13338 
13339     // Record the expression we've just processed.
13340     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13341 
13342     // Create a mappable component for the list item. List items in this clause
13343     // only need a component. We use a null declaration to signal fields in
13344     // 'this'.
13345     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13346             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13347            "Unexpected device pointer expression!");
13348     MVLI.VarBaseDeclarations.push_back(
13349         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
13350     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13351     MVLI.VarComponents.back().push_back(MC);
13352   }
13353 
13354   if (MVLI.ProcessedVarList.empty())
13355     return nullptr;
13356 
13357   return OMPIsDevicePtrClause::Create(
13358       Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13359       MVLI.VarBaseDeclarations, MVLI.VarComponents);
13360 }
13361